简体   繁体   English

C++ istream 输入失败但仍在消耗数据。 期望在失败后能够读取坏数据

[英]C++ istream input fails yet consumes data. Expected to be able read bad data after failure

My understanding of iostream has always been that when an input conversion fails, the data remains in the stream to be read after clearing the error.我对iostream的理解一直是当一个输入转换失败时,数据会留在stream中,待清除错误后读取。 But I have an example that does not always work that way, and I would like to know if the behavior is correct.但是我有一个例子并不总是那样工作,我想知道这种行为是否正确。 If so, could someone point me at some good documentation of the actual rules?如果是这样,有人可以指点我一些关于实际规则的好文档吗?

This small program represents the idea of using an i/o failure to read an optional repeat count and a string.这个小程序代表了使用 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;
}

So, here's how it runs:所以,这是它的运行方式:

[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 [@(#&$(@#&$]

So it mostly works.所以它主要有效。 When there's a number first, it is read, then the string is.当先有一个数字时,它被读取,然后是字符串。 When I give a non-numeric first, the read fails, the count is set to 1 and the non-numeric input is read.当我先给出一个非数字时,读取失败,计数设置为 1 并读取非数字输入。 But this breaks:但这打破了:

[me@localhost tmp]$ ./bother 
in: + smith
out: 1 [smith]

The + fails the integer read because it's not enough to make a number, but the + does not remain on the stream to be picked up by the string read. + 无法读取 integer,因为它不足以构成一个数字,但 + 不会保留在 stream 上以供读取的字符串拾取。 Likewise with -.同样与 - 。 If it reads the + or - as a zero, that would be reasonable, but then the read should succeed and cnt should show that zero.如果它读取 + 或 - 为零,那将是合理的,但读取应该成功并且 cnt 应该显示该零。

Perhaps this is correct behavior, and I've just always been wrong about what it is supposed to do.也许这是正确的行为,而我一直对它应该做什么是错误的。 If so, what are the rules?如果这样,规则是什么?

Your advice appreciated.感谢您的建议。

Plus and minus are valid parts of an integer and so are read, when the next character is read the stream fails and that character is left in the stream but the leading sign character is not put back into the stream.加号和减号是 integer 的有效部分,因此被读取,当读取下一个字符时,stream 失败并且该字符留在 stream 中,但前导字符不会放回 stream。

See https://en.cppreference.com/w/cpp/locale/num_get/get for the full rules有关完整规则,请参阅https://en.cppreference.com/w/cpp/locale/num_get/get

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM