【发布时间】:2020-02-21 09:16:49
【问题描述】:
我通常教我的学生处理文件输入的安全方法是:
while (true) {
// Try to read
if (/* failure check */) {
break;
}
// Use what you read
}
这使我和许多人摆脱了经典且大部分时间都是错误的:
while (!is.eof()) {
// Try to read
// Use what you read
}
但是人们真的很喜欢这种形式的循环,所以在学生代码中看到这种形式变得很普遍:
while (is.peek()!=EOF) { // <-- I know this is not C++ style, but this is how it is usually written
// Try to read
// Use what you read
}
现在的问题是:这段代码有问题吗?是否存在一些事情不能完全按预期工作的极端情况?好的,这是两个问题。
编辑其他详细信息:在考试期间,您有时会向学生保证文件格式正确,因此他们无需进行所有检查,只需验证是否有更多数据.大多数时候我们处理二进制格式,这让你完全不用担心空格(因为数据都是有意义的)。
虽然公认的答案是完全清楚和正确的,但我仍然希望有人尝试评论 peek() 和 unget() 的联合行为。
unget() 的东西浮现在我的脑海,因为我曾经观察到(我相信它是在 Windows 上)通过查看 4096 内部缓冲区限制(如此有效地导致加载新缓冲区),取消了前一个字节(上一个缓冲区的最后一个)失败。但我可能是错的。所以这是我的另一个疑问:我错过了一些已知的东西,它可能在标准或某些库实现中得到了很好的编码。
【问题讨论】:
-
你会想看看Why !.eof() inside a loop condition is always wrong. 第四个条件稍微好一点。通常总是更好地使用读取功能本身来控制读取,例如
while (std::cin >> var) { /* handle var */ }或while (getline (fp, str)) { /* handle string */ }等等...