使用std :: istream :: peek()总是安全吗?

问题描述 投票:3回答:1

我通常教我的学生,处理文件输入的安全方法是:

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
}

现在的问题是:这段代码有问题吗?在某些极端情况下,事情无法按预期进行吗?好的,这是两个问题。

c++ istream
1个回答
3
投票

is.peek()!=EOF告诉您输入流中是否还剩下字符,但不会告诉您下一次读取是否成功:

while (is.peek()!=EOF) {
    int a;
    is >> a;
    // Still need to test `is` to verify that the read succeeded
}

is >> a可能由于多种原因而失败,例如输入的内容实际上可能不是数字。

因此,如果可以的话,这没有任何意义

int a;
while (is >> a) { // reads until failure of any kind
    // use `a`
}

或者,也许更好:

for (int a; is >> a;) { // reads until failure of any kind
    // use `a`
}

或您的第一个示例,在这种情况下,循环中的is.peek()!=EOF将变得多余。

这是假设您希望循环在每次失败时都退出,遵循第一个代码示例,而不仅仅是在文件末尾。

© www.soinside.com 2019 - 2024. All rights reserved.