使用字符串流解析字符串时,它会提取换行符

When parsing a string using a string stream, it extracts a new line character

程序说明:程序必须读入可变数量的单词,直到指定标记值(在本例中为“#”)。它将单词存储在向量数组中。

问题: 我使用 getline 读取字符串并使用 stringstream 解析字符串。我的问题是 stringstream 没有吞下每行末尾的换行符,而是提取它。

我想到的一些解决方案是通过创建子集或检查下一个提取的单词是否为换行符来截断最后一个字符,但我觉得有更好的成本效益解决方案,例如更改条件对于我的循环。

我已经包含了重现问题的整体代码的最小化版本。

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main()
{
   const int MAX_LIST_SIZE = 1000;
   string str;
   string list[MAX_LIST_SIZE];
   int numWords = 0;

   // program starts here
   getline(cin, str);          // read innput
   stringstream parse(str);    // use stringstream to parse input

   while(str != "#")           // read in until sentinel value
   {
       while(!parse.fail())    // until all words are extracted from the line    
       {
           parse >> list[numWords];    // store words
           numWords++;
       }
       getline(cin,str);      // get next line
       parse.clear();
       parse.str(str);
   }

   // print number of words
   cout << "Number of words : " << numWords << endl;
}

以及会产生问题的一组测试输入数据

输入:

apples oranges mangos
bananas 
pineapples strawberries

输出:

Number of words : 9

预期输出:

Number of words : 6

对于如何有效处理此问题的任何建议,我将不胜感激。

numwords 的增量在每行末尾发生的次数比您预期的多一次。使用 std::vector< std::string > 作为您的列表。然后你可以使用 list.size().

您解析流的逻辑不太正确。 fail() 仅在 后 变为真 >> 操作失败,因此您每次都会进行额外的增量。例如:

   while(!parse.fail())  
   {
       parse >> list[numWords];    // fails
       numWords++;                 // increment numWords anyway
   }                           // THEN check !fail(), but we incremented already!

所有这些操作都有 returns,您应该在执行过程中进行检查以避免出现此问题:

while (getline(cin, str)) { // fails if no more lines in cin
    if (str != "#") {       // doesn't need to be a while
        stringstream parse(str);
        while (parse >> list[numWords]) { // fails if no more words
            ++numWords;                   // *only* increment if we got one!
        }
    }
}

更好的办法是完全不为单词列表使用数组:

std::vector<std::string> words;

可以在内循环中使用:

std::string temp;
while (parse >> temp) {
    words.push_back(temp);
}