做这个stl运算符>>功能让魔术发生?

时间:2016-04-22 16:46:30

标签: c++ stl istringstream

当我测试c ++ STL功能时,我遇到了一个奇怪的问题。如果我取消注释行if(eee),我的while循环永远不会退出 我在64位Windows下使用vs2015。

    int i = 0;
    istream& mystream = data.getline(mycharstr,128);
    size_t mycount = data.gcount();
    string str(mycharstr,mycharstr+mycount);
    istringstream myinput(str);
    WORD myfunclist[9] = {0};
    for_each(myfunclist,myfunclist+9, [](WORD& i){ i = UINT_MAX;});
    CALLEESET callee_set;
    callee_set.clear();
    bool failbit = myinput.fail();
    bool eof = myinput.eof();
    while (!failbit && !eof)
    {
        int eee = myinput.peek();
        if (EOF == eee) break;
        //if (eee) // if i uncomment this line ,the failbit and eof will always be false,so the loop will never exit.
        {
            myinput >> myfunclist[i++];
        }
        //else break;
        failbit = myinput.fail();
        eof = myinput.eof();
        cout << myinput.rdstate() << endl;
    }

2 个答案:

答案 0 :(得分:1)

我认为

int eee = myinput.peek();

在某一时刻返回零。

然后由于

if (eee)

你停止从流中读取并且永远不会达到EOF。

尝试

if (eee >= 0)

代替

作为替代方案,您可以这样做:

    if (eee < 0)
    {
        break;
    }

    // No need for further check of eee - just do the read
    myinput >> myfunclist[i++];

答案 1 :(得分:0)

您问题的根本原因是对流设置其标志的方式的误解:fail()eof() 仅在读取操作失败或在到达最后一个字节后尝试读取时才设置。

换句话说,使用 C++ 流,您可能已经完全读取了输入的最后一个字节并位于文件末尾,但是 eof() 将保持为 false,直到您尝试阅读更多内容。您会在 StackOverflow 上找到许多关于为什么 you should not loop on eof in a C++ stream 的问题和答案。

后果:

  • 您将始终进入循环,即使 myinput 中没有可读取的字符。
  • 因此,您必须检查 peek() 返回 EOF 的特殊情况。
  • 如果您在窥视后仍处于循环中,则仍有要阅读的字符。请记住,peek() 不消耗字符。如果您没有以正确的方式阅读它,您将停留在流中的同一位置。因此,如果由于某种原因您没有到达 myinput >> myfunclist[i++];,您将陷入无限循环,不断地一遍又一遍地偷看同一个角色。这就是 4386427's answer 中详细描述的 0 情况:它仍然存在并且您没有在流中取得进展。

其他评论:

  • 由于您的输入可能有 128 个字节长,并且您以文本编码读取整数,因此您可能会收到包含 64 个不同单词的恶意输入,从而导致您的循环超出 ov 边界并导致例如内存损坏。
  • 不清楚你为什么要偷看。

我建议忘记标志,使用通常的流阅读习惯并将代码简化为:

... 
callee_set.clear();  // until there, no change

while (i<9 && myinput >> myfunclist[i++])
{
   cout << myinput.rdstate() << endl; // if you really want to know ;-)    
}