我正在运行一本C ++教科书,我将其作为C ++编程的复习。其中一个实践问题(没有详细说明)要我定义一个可以传递ifstream或cin(例如istream)作为参数的函数。从那里,我必须通读流。麻烦的是,我无法想办法让这个一个函数使用cin和ifstream来有效地找到流的结尾。即,
while(input_stream.peek() != EOF)
不适用于cin。我可以修改函数来查找某个短语(比如“#End of Stream#”等),但我认为如果我传递的文件流有这个确切的短语,这是一个坏主意。
我曾想过使用函数重载,但到目前为止,本书已经提到它何时需要我这样做。我可能在这个练习题上花了太多精力,但我喜欢创作过程,如果有这样的方法可以做到这一点而没有超载,我很好奇。
答案 0 :(得分: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生成)
答案 1 :(得分:2)
为什么std::cin.eof()
不起作用?当stdin关闭时,cin
将发出EOF信号,这将在用户用 Ctrl + d (* nix)或 Ctrl + z (Windows)发出信号时发出信号,当管道文件结束时(或者在管道输入流的情况下)
答案 2 :(得分:2)
如果你在一个布尔上下文中使用一个流,那么它会将自身转换为一个值,如果它没有达到EOF,则等于true;如果尝试读取超过EOF,则将其转换为false(不是它也是如果从流中读取了先前的错误,则为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).
}