C++输入流失败但却消耗数据。预期在失败后能够读取错误的数据。

4

我一直以为iostream是这样的:当输入转换失败时,数据仍然存在流中,在清除错误后可以读取。但我有一个例子并不总是按照这种方式工作,我想知道这种行为是否正确。如果是,能否有人指向一些好的实际规则文档?

这个小程序代表了使用i/o失败来读取可选重复计数和字符串的思想。

#include <iostream>
#include <string>

int main()
{
    int cnt;
    std::cout << "in: ";
    std::cin >> cnt;
    if(!std::cin) {
        cnt = 1;
        std::cin.clear();
    }
    std::string s;
    std::cin >> s;
    std::cout << "out: " << cnt << " [" << s << "]" << std::endl;
}

所以,它的运行方式如下:

[me@localhost tmp]$ ./bother 
in: 16 boxes
out: 16 [boxes]
[me@localhost tmp]$ ./bother 
in: hatrack
out: 1 [hatrack]
[me@localhost tmp]$ ./bother 
in: some things
out: 1 [some]
[me@localhost tmp]$ ./bother 
in: 23miles
out: 23 [miles]
[me@localhost tmp]$ ./bother 
in: @(#&$(@#&$ computer
out: 1 [@(#&$(@#&$]

所以它大多数时候是有效的。当第一个是数字时,它会读取数字,然后再读取字符串。当我给出一个非数字作为第一个时,读取失败,计数器被设置为1并且读取非数字输入。但这会导致错误:
[me@localhost tmp]$ ./bother 
in: + smith
out: 1 [smith]

+ 号无法成功读取整数,因为它不足以组成一个数字,但是 + 号并没有留在流中由字符串读取。 - 号同理。如果将 + 或 - 读取为零,则这是合理的,但是读取应该成功,cnt 应显示为零。

也许这是正确的行为,我一直误解了它应该做什么。如果是这样,那么规则是什么呢?

感谢您的建议。


1
从输入流中提取字符在失败点停止。 - David C. Rankin
或许 . 会产生类似的效果。- 肯定会。无论如何,它们都是数字的有效部分,但不能单独组成一个数字。 - Ulrich Eckhardt
1个回答

2

谢谢。虽然这个标准似乎更像是“祝福现有的随机黑客”而不是“它应该表现出最干净的方式。” - T W Bennet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接