为啥字符串流的循环给我最后一个字两次[重复]

Posted

技术标签:

【中文标题】为啥字符串流的循环给我最后一个字两次[重复]【英文标题】:Why does loop for stringstream give me the last word twice [duplicate]为什么字符串流的循环给我最后一个字两次[重复] 【发布时间】:2018-12-07 03:52:54 【问题描述】:

我正在尝试在stringstream 的帮助下逐字循环字符串,这是我的代码:

string str = "hello world";
stringstream ss(str);
string word;
while (ss)

    ss >> word;
    cout << word << endl;

但是,我得到的结果如下:

hello
world
world

为什么我得到了两次world

【问题讨论】:

while(ss &gt;&gt; word) ... 完成。您检查流是否良好,阅读,打印,重复。如果读取失败,则流是错误的,但您在再次检查并退出循环之前打印。正确的做法是仅在实际 i/o 操作成功时才​​使用您已读取或写入的数据。 【参考方案1】:

使用此代码 sn-p:

while (ss)  ...  

您正在检查string stream 的状态。如果它包含有效数据,则循环将继续。这就是为什么你看到最后一个字两次...

1st 循环迭代:

while ( ss )              // checks if there is valid data in ss and for errors (true)
    ss >> word;            // ss inserts "hello" into word.
    cout << word << endl;  // cout prints "hello" to the console.

2nd 循环迭代:

while ( ss )              // checks again if there is valid data (true)
    ss >> word;            // ss inserts "world" into word.
    cout << word << endl;  // cout prints "world" to the console.

3rd 循环迭代:

while ( ss )              // checks again if there is valid data (true)
    ss >> word;            // ss already contains "world", may optimize or copy over...
    cout << word << endl;  // cout prints "world" to the console.

4次循环迭代:

while ( ss )              // ss encountered end of stream (false) exits loop.
    ss >> word;            // nothing inserted as loop has exited.
    cout << word << endl;  // nothing printed as loop has exited.


与其尝试使用您的stringstream 作为循环条件,不如尝试使用从stringstream 中提取数据到您的条件变量中的过程。

while( ss >> word ) 
    cout << word << endl;


1st 循环迭代:

while ( ss >> word )        // checks if ss inserted data into word
                             // ss inserts "hello" (true)
    cout << word << endl;    // cout prints "hello" to the console.

2nd 循环迭代:

while ( ss >> word )       // checks again if ss inserted data into word
                            // ss inserts "world" into word (true)
    cout << word << endl;   // cout prints "world" to the console.

3rd 循环迭代:

while ( ss >> word )       // checks again if ss inserted data into word
                            // ss fails to insert data (false) loop exits here
    cout << word << endl;   // nothing printed as loop exited

【讨论】:

【参考方案2】: while (ss) 看到 ss 还没有遇到问题,所以它运行循环体。 (当您使用 ss 作为布尔值时会发生这种情况) ss &gt;&gt; word; 读作“你好” cout &lt;&lt; word &lt;&lt; endl; 打印“你好” while (ss) 看到 ss 还没有遇到问题,于是再次运行循环体。 ss &gt;&gt; word; 读作“世界” cout &lt;&lt; word &lt;&lt; endl; 打印“世界” while (ss) 看到 ss 还没有遇到问题,于是再次运行循环体。 ss &gt;&gt; word; 看到没有更多数据,所以它失败了。 word 没有改变,它仍然包含“世界” cout &lt;&lt; word &lt;&lt; endl; 打印“世界” while (ss) 看到 ss 遇到问题并停止循环。

你需要检查是否在读完单词之后停止循环。例如,使用:

while (true)

    ss >> word;
    if (!ss)
        break;
    cout << word << endl;

或简称:

while (ss >> word)

    cout << word << endl;

【讨论】:

为什么不直接while(ss &gt;&gt; word) ...

以上是关于为啥字符串流的循环给我最后一个字两次[重复]的主要内容,如果未能解决你的问题,请参考以下文章

获取字符串流中的最后一个字符而不复制其整个缓冲区

如何使用 C++ 字符串流附加 int?

为啥我的程序接受用户输入的次数不超过两次?

为啥这个while循环在输入的每个字符之后重复?

为啥dma只接收最后一个字符

从字符串读取到字符串流