istream末尾的字符问题

时间:2014-09-23 01:14:32

标签: c++ iostream

我正在编写一个解析器,当我尝试解析标识符(对C ++变量名有效的任何内容)和未关闭的字符串文字(以"开头的任何内容时,我以前遇到了麻烦,但是错过了结束")在我的输入结束时。我认为这是因为词法分析器(TokenStream)在这些情况下使用std::noskipws并按字符构建标记字符。这是我认为我已经缩小了问题的范围(仅针对两种情况中的一种显示,因为另一种情况非常相似):

std::string TokenStream::get()
{
    char c;
    (*input) >> c; // input is of type istream*

    // other cases...

    if (c == '"')
    {
        std::string s = stringFromChar(c); // just makes a string from the char.
        char d;
        while (true) // 1)
        {
            (*input) >> std::noskipws >> d;
            std::cout << d; // 2)
            if (d == '"')
            {
                s += d;
                (*input) >> std::skipws;
                break; 
            }
            s += d;
        }
        return s;
    }

    // other cases...
}

请注意,此函数应该只是以类似流的方式从输入生成标记。现在,如果我输入文字(如asdf)或未关闭的字符串(如"asdf),则程序将挂起,标记为2)的行将只输出最后一个字符输入(在我的例子中,f)一遍又一遍地重复。

我使用input->eof()检查解决了这个问题,但我的问题是:

为什么循环(在评论中标记为1))在我到达流的末尾时继续执行,为什么它只是打印每次循环读取的最后一个字符?

1 个答案:

答案 0 :(得分:1)

让我们逐行查看有问题的循环

    while (true) // 1)

除非遇到休息,否则会循环播放

    {
        (*input) >> std::noskipws >> d;

读一个角色。如果无法读取字符,d可能会保持不变。

        std::cout << d; // 2)

打印刚读过的字符

        if (d == '"')

不,最后一个字符不是"(在问题中指定)

        {
            s += d;
            (*input) >> std::skipws;
            break; 
        }
        s += d;
    }

因此,永远不会遇到中断,并且最后一个字符以无限循环打印。


修复:总是使用一段时间看起来像输入:

char ch;
while (input >> ch) {

    // ch contains a new letter, deal with it

}