我对C++还是很陌生,所以如果这不是一个好问题,我深表歉意,但是在理解如何使用istream方面我确实需要帮助。

我必须创建一个项目,该项目需要在一行或多行上输入多个输入,然后将其传递给 vector (这只是该项目的一部分,我想自己尝试其余的输入) ,例如,如果我要输入...

>> aaa    bb
>> ccccc
>> ddd fff  eeeee

用“aaa”,“bb”,“ccccc”,“ddd”,“fff”,“eeeee”制作字符串 vector

输入可以是char或字符串,并且在按下回车键时程序会停止要求输入。

我知道getline()获得一行输入,并且我可能可以使用while循环尝试获取诸如...的输入(如果我错了,请纠正我)
while(!string.empty())
     getline(cin, string);

但是,我并不真正了解istream,并且我的类(class)没有遍历指针也无济于事,所以我不知道如何使用istream&或string&将其传递给 vector 。在项目描述中,它说不使用stringstream而是使用getline(istream&,string&)中的功能。关于如何使用getline(istream&,string&)创建函数,然后如何在main函数中使用它,谁能给出一些详细的解释?

一点帮助!

最佳答案

您已经走对了路;完全是这样,您必须用一些虚拟对象预填充字符串才能完全进入while循环。更优雅:

std::string line;
do
{
    std::getline(std::cin, line);
}
while(!line.empty());

如果用户输入一个空行,这应该已经逐行完成了技巧的读取(但是可能在一行上有多个单词!)并退出了(请注意,空格和换行符不会被这样识别!)。

但是,如果流中有任何错误,您将陷入一个无限循环中,一次又一次地处理先前的输入。因此,最好同时检查流状态:
if(!std::getline(std::cin, line))
{
    // this is some sample error handling - do whatever you consider appropriate...
    std::cerr << "error reading from console" << std::endl;
    return -1;
}

由于一行上可能有多个单词,因此您必须将它们分开。这样做有多种方法,使用std::istringstream是一种非常简单的方法-您会发现它类似于您可能使用的std::cin:
    std::istringstream s(line);
    std::string word;
    while(s >> word)
    {
        // append to vector...
    }

请注意,使用operator>>会忽略开头的空格,并在第一个尾随空格(或流的末尾,如果到达)之后停止,因此您不必显式处理。

好的,您不允许使用std::stringstream(好吧,我使用std:: stringstream,但是我想这个小区别不算在内,对吗?)。更改有一点点,它变得更加复杂,另一方面,我们可以自行决定将什么视为单词,将什么视为分隔符...我们可以将标点符号视为分隔符,就像空格一样,但是允许数字成为单词的一部分,所以我们接受e。 G。 ab.7c d作为"ab", "7c", "d":
auto begin = line.begin();
auto end = begin;
while(end != line.end()) // iterate over each character
{
    if(std::isalnum(static_cast<unsigned char>(*end)))
    {
        // we are inside a word; don't touch begin to remember where
        // the word started
        ++end;
    }
    else
    {
        // non-alpha-numeric character!
        if(end != begin)
        {
            // we discovered a word already
            // (i. e. we did not move begin together with end)
            words.emplace_back(begin, end);
            // ('words' being your std::vector<std::string> to place the input into)
        }
        ++end;
        begin = end; // skip whatever we had already
    }
}
// corner case: a line might end with a word NOT followed by whitespace
// this isn't covered within the loop, so we need to add another check:
if(end != begin)
{
    words.emplace_back(begin, end);
}

适应什么是分隔符以及什么算作单词(例如std::isalpha(...) || *end == '_'以将下划线检测为单词的一部分,而不使用数字)的不同解释应该不太困难。您可能会发现很多helper functions有用...

关于c++ - 如何在C++中使用istream&,string&和getline读取复杂的输入?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53379153/

10-11 22:46
查看更多