7

我正在阅读一本 C++ 教科书,作为 C++ 编程的复习。其中一个实践问题(无需过多介绍)要我定义一个可以作为参数传递 ifstream 或 cin(例如 istream)的函数。从那里,我必须通读流。麻烦的是,我想不出一种方法让这个函数使用 cin 和 ifstream 来有效地找到流的结尾。即,

while(input_stream.peek() != EOF)

不会为cin工作。我可以修改函数以查找某个短语(例如“#End of Stream#”或其他内容),但我认为如果我传递的文件流具有这个确切的短语,那么这是一个坏主意。

我曾想过使用函数重载,但到目前为止,这本书已经提到了它想要我这样做的时候。我可能在这个练习题上投入了太多精力,但我喜欢创作过程,并且很好奇是否有这样一种方法可以做到这一点而不会超载。

4

3 回答 3

6

eof() cin有效。你做错了什么;请发布您的代码。一个常见的绊脚石是,您尝试在流末尾读取之后eof设置标志。

这是一个演示:

#include <iostream>
#include <string>

int main( int, char*[] )
{
    std::string s;
    for ( unsigned n = 0; n < 5; ++n )
    {
        bool before = std::cin.eof();
        std::cin >> s;
        bool after = std::cin.eof();
        std::cout << int(before) << " " << int(after) << "  " << s << std::endl;
    }

    return 0;
}

及其输出:

D:>t
aaaaa
0 0  aaaaa
bbbbb
0 0  bbbbb
^Z
0 1  bbbbb
1 1  bbbbb
1 1  bbbbb

(在 Windows 上可以使用 Ctrl-Z 生成 EOF,在许多其他操作系统上可以使用 Ctrl-D 生成)

于 2010-08-30T18:26:09.490 回答
2

为什么std::cin.eof()行不通?cin将在标准输入关闭时发出 EOF 信号,这将在用户使用Ctrl+d(*nix) 或Ctrl+z(Windows) 发出信号时发生,或者(在管道输入流的情况下)当管道文件结束时发生

于 2010-08-30T18:22:17.030 回答
2

如果您在布尔上下文中使用流,那么它会将自身转换为一个值,如果它没有达到 EOF,则它相当于 true;如果尝试读取 EOF,它会转换为 false(如果有是从流中读取的先前错误)。

由于流上的大多数 IO 操作都返回流(因此可以将它们链接起来)。您可以进行读取操作并在测试中使用结果(如上)。

所以一个从流中读取数字流的程序:

int main()
{
   int x;

   // Here we try and read a number from the stream.
   // If this fails (because of EOF or other error) an internal flag is set.
   // The stream is returned as the result of operator>>
   // So the stream is then being used in the boolean context of the while()
   // So it will be converted to true if operator>>  worked correctly.
   //                         or false if operator>> failed because of EOF
   while(std::cin >> x)
   {
       // The loop is only entered if operator>> worked correctly.
       std::cout << "Value: " << x << "\n";
   }

   // Exit when EOF (or other error).
}
于 2010-08-30T18:39:32.347 回答