无效数字总是降到0?

Jos*_*hua 2 c++ cin

cout << "Enter a positive integer or zero: ";
getline(cin, streamStr);
stringstream(streamStr) >> number;
if (!number) {
    cout << "invalid input detected or the input is too big.\n";
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

像"%234"或"sdf2334"这样的输入总是下降到0,这在bool表达式中是假的,但0仍然是一个数字.如何检查输入是否真的像"%234"一样无效?

Bar*_*icz 5

您需要检查返回的值operator>>,这与您正在读取的变量的值不同:

if (stringstream(streamStr) >> number) {
    ...
Run Code Online (Sandbox Code Playgroud)

那么什么是返回值呢?如果你检查文档,你会发现它本身就是一个流.它转到operator bool它(因为它在一个if语句中使用),它反过来返回流的有效性,或者IOW,如果最后一个操作成功.

如果要确保流不包含除数字使用之外的任何内容

if (sstream.rdbuf()->in_avail() > 0) { 
    // something is still there
Run Code Online (Sandbox Code Playgroud)

如果你想允许的话,最后跳过空格:

sstream >> std::ws;
Run Code Online (Sandbox Code Playgroud)

总而言之......

template<typename T, 
    // those are optional
    enable_if<is_default_constructible<T>::value>::type,
    enable_if<is_input_streamable<T>::value>::type
>
optional<T> myRead(string input, bool allowTrailingWs = true) {
    stringstream str(input);
    T val;

    // check parsing
    if (!(str >> val))
        return none;

    // allow whitespace at the end
    if (allowTrailingWs)
        str >> std::ws;

    // check if there's any garbage left
    if (str.rdbuf()->in_avail() > 0)
        return none;

    return val;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码仅用于说明目的.如果你需要更高级的解析,请查看Boost.Spirit.


而且,显然这并不能保证每次都能正常工作.使用:

    auto inputEnd = ss.tellg();
    ss.seekg(0, std::ios::end);
    if (inputEnd == ss.tellg()) {
Run Code Online (Sandbox Code Playgroud)

检查是否ss为空可以帮助解决这个问题.