在数组中使用getline()

问题描述 投票:0回答:2

[今天,我正在编写一个程序,基本上它采用了您以前访问过的城市的路线,最后它应该返回您整个旅行的路线,即路线。

在第一行中,您输入的是您过去访问过的城市数(包括您的居住城市),N

假设我们的家乡是巴黎。在第二行中,输入您的家乡(在我们的情况下为Paris)。

在接下来的N行中输入您的旅行路线,它们不需要像您一样排列,因此可以按照任何顺序排列:

输入:

4  
Paris  
Berlin-Paris  
Paris-Zagreb  
Ljubljana-Berlin   
Zagreb-Ljubljana  

输出:

Paris-Zagreb-Ljubljana-Berlin-Paris

这是我用c ++编写的代码:

#include <iostream>
#include <string>
using namespace std;
string s[1000],city;
int n;  

int main(){
    cin>>n;
    cin>>city;
    for(int i=0;i<n;i++){
        cin>>s[i];
    }
    cout<<city;
    for(int j=0;j<n;j++){
        for(int i=0;i<n;i++){
            if(s[i].substr(0,city.length())==city){
                city=s[i].substr(city.length()+1);
            cout<<"-"<<city;
            s[i]='\0';
            }   
        }   
    }


}

[这不是最有效的方法,我知道...而且它仅适用于单字城市(不适用于纽约和其他2个或更多带有文字的城市)

现在我的问题是,有没有简单的方法可以对2个以上有文字的城市(例如纽约)进行处理?我尝试使用getline(cin,city)和getline(cin,s [i]),但由于某些原因它无法正常工作,也许我没有正确执行。

[尝试使用getline()时,我注意到当我尝试使用getline()输入字符串s [i]时,我的循环for(int i=0;i<n;i++)仅进入n-1,这意味着我无法在该数组中输入n个字符串例如,如果我使用N = 5,则只能输入4个字符串

for(int i=0;i<5;i++){
    getline(cin,s[i]);
}

让我输入4个字符串,同时

for(int i=0;i<5;i++){
    cin>>s[i];
}

让我输入5个字符串


另外我还注意到,如果我有一些简单的代码:

#include <iostream>
#include <string>
using namespace std;
string city;
int n;  

int main(){
    cin>>n;
    getline(cin,city);
    cout<<city;
}

我以为它应该输出城市的名称,但不是这样,有人可以解释为什么吗?

也许我正在丢失某些东西,仅此而已...感谢您的阅读,如果您知道答案,请帮助我:)

c++ arrays string getline
2个回答
0
投票

现在我的问题是,有没有简单的方法可以对2个以上措词的城市(例如纽约)进行处理?

是的,这应该具有相同的效果,但是允许2个以上的单词城市:

#include <iostream>
#include <string>
using namespace std;
string s[1000],city;
int n;  

int main(){
    string nStr;
    getline(cin, nStr);
    // converting string input to an integer
    n = stoi(nStr);
    getline(cin, city);
    for(int i=0;i<n;i++){
        getline(cin, s[i]);
    }
    cout<<city;
    for(int j=0;j<n;j++){
        for(int i=0;i<n;i++){
            if(s[i].substr(0,city.length())==city){
                city=s[i].substr(city.length()+1);
            cout<<"-"<<city;
            s[i]='\0';
            }   
        }   
    }
}

输入:5巴黎柏林纽约巴黎-萨格勒布卢布尔雅那-柏林萨格勒布-卢布尔雅那纽约-巴黎

输出:巴黎-萨格勒布-卢布尔雅那-柏林-纽约-巴黎

我以为它应该输出城市的名称,但这不是一个的情况下,有人可以解释为什么吗?

[This答案解释了cin在流中放置了换行符,getline会立即将其读入city并打印换行符,因此看起来什么都没有发生。


0
投票

有没有简单的方法可以对2个以上的措词城市进行处理,例如纽约?

答案:是。

正如@jackw11111的答案所指出的,您在读取包含whitespace的名称时遇到的问题是由于std::cin仅从行的开头到第一个whitespace读取。因此,例如,尝试用"New York"读取std::cin >> city;会导致city包含"New",而"York"仍处于stdin未读取状态。

解决方案是使用getline,它将读取直到指定分隔符为止(默认值:'\n')。

现在,对于问题的其余部分,读取两个(或多个)城市之间以'-'分隔的行程,有多种方法可以解决该问题。由于旅行的每一段都将包含一个[[from和to城市,因此使用STL中提供的std::pair作为utility标头的一部分将提供一种方便的方式来存储相关的[[from和to个城市。然后,您可以使用std::vector<std::pair<..,..>>创建vector-of-pairs

除非您绝对需要读取行进次数的第一个整数值,否则就可以删除它,因为它实际上并不需要处理输入。实际上,您所需要的只是您的std::vector<std::pair<..,..>>城市,然后您可以根据需要读取任意多行输入,并存储尽可能多的行对[[fromto城市对,直到从home中读取文件,或输入空白行以表示输入结束。

使用EOF分隔用getline读取的行。要从std::stringstream中读取,可以再次使用std::stringstream(带有getline分隔符)来分隔行中的[[from-to城市。将行放入字符串流中,然后从字符串流中进行读取,可防止在分隔符更改为其他内容时,'-'跳过getline

因此,在您的情况下,您可以声明字符串对的向量以及一些其他字符串来容纳'\n'并帮助进行解析,并且您可以简单地首先读取home城市,例如home

现在只需循环读取输入行,并检查该行是否为空以指示输入结束。从每条线创建一个字符串流,然后使用#include <iostream> #include <sstream> #include <string> #include <utility> #include <vector> int main (void) { std::string home, last, trip, total; /* strings */ std::vector<std::pair<std::string, std::string>> vp {}; /* vector of pairs */ std::cout << "enter home city: "; /* prompt for home city */ if (!getline (std::cin, home)) { /* read/validate home city */ std::cerr << "error: failed to read home-city.\n"; return 1; } 从字符串流中读取(这消除了使用getline从该行解析城市的需要)。使用substr

将每对从-到城市添加到向量中

std::make_pair

最后,只需循环遍历您的存储对(使用嵌套循环)即可基于

from-to

选择所有行程分支,然后通过设置 /* prompt for trips (any number of legs per-line), ENTER alone when done */ std::cout << "\nenter trips (format city1-city2[-cityN]) " "[Enter] alone when done\n\ntrip: "; while (getline (std::cin, trip)) { /* while trip entered */ if (!trip.length()) /* if empty (zero length) break */ break; std::stringstream ss (trip); /* create stringsteam from line */ std::string from, to; /* strings for from and to cities */ if (getline (ss, from, '-')) { /* get from city from stringstrem */ while (getline (ss, to, '-')) { /* get to city from stringstream */ vp.push_back(std::make_pair (from, to)); /* add pair to vector */ from = to; /* update from = to */ } } std::cout << "trip: "; /* prompt for next trip */ } 并找到下一个匹配项来找到下一个行程分支。 (您还可以添加其他检查,以确保在每次迭代中都找到正确的from-to-留给您-像from = to;这样的简单操作即可)]
bool found;

(<< [note:使用 total = home; /* initialize total & last to home */ last = home; for (auto t1 : vp) { /* loop over each trip */ for (auto t2 : vp) { /* 2nd search loop */ if (t2.first == last) { /* find trip begins with last city */ total += "-" + t2.second; /* add trip end to total */ last = t2.second; /* update last to end */ break; /* go find next trip */ } } } std::cout << '\n' << total << '\n'; /* output total trip beg to end */ 访问每个std::pair中的第一个对象,然后使用.first访问第二个对象-甚至有些逻辑...)

您可以想出很多变化。综上所述,您可以执行以下操作:.second

示例使用/输出

#include <iostream> #include <sstream> #include <string> #include <utility> #include <vector> int main (void) { std::string home, last, trip, total; /* strings */ std::vector<std::pair<std::string, std::string>> vp {}; /* vector of pairs */ std::cout << "enter home city: "; /* prompt for home city */ if (!getline (std::cin, home)) { /* read/validate home city */ std::cerr << "error: failed to read home-city.\n"; return 1; } /* prompt for trips (any number of legs per-line), ENTER alone when done */ std::cout << "\nenter trips (format city1-city2[-cityN]) " "[Enter] alone when done\n\ntrip: "; while (getline (std::cin, trip)) { /* while trip entered */ if (!trip.length()) /* if empty (zero length) break */ break; std::stringstream ss (trip); /* create stringsteam from line */ std::string from, to; /* strings for from and to cities */ if (getline (ss, from, '-')) { /* get from city from stringstrem */ while (getline (ss, to, '-')) { /* get to city from stringstream */ vp.push_back(std::make_pair (from, to)); /* add pair to vector */ from = to; /* update from = to */ } } std::cout << "trip: "; /* prompt for next trip */ } total = home; /* initialize total & last to home */ last = home; for (auto t1 : vp) { /* loop over each trip */ for (auto t2 : vp) { /* 2nd search loop */ if (t2.first == last) { /* find trip begins with last city */ total += "-" + t2.second; /* add trip end to total */ last = t2.second; /* update last to end */ break; /* go find next trip */ } } } std::cout << '\n' << total << '\n'; /* output total trip beg to end */ }

也可以输入为:

$ ./bin/triptotal
enter home city: Paris

enter trips (format city1-city2[-cityN]) [Enter] alone when done

trip: Berlin-Paris
trip: Paris-New York
trip: New York-Zagreb
trip: Ljubljana-Berlin
trip: Zagreb-Ljubljana
trip:

Paris-New York-Zagreb-Ljubljana-Berlin-Paris

您将要完成的另一项任务是找到一种方法来处理可能会访问同一城市的多条行程。 (这也留给您了)仔细检查一下,如果还有其他问题,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.