cin double 和没有 space 的字符串导致错误

cin double and string without space results in error

下面的程序在输入 10cm 时在 Mac Mojave (AppleClang 10.0.1.10010046) 上输出 Error(注意在 space 之间没有 space值和字符串输入)。同样的输入在 Ubuntu 16.04 (GNU 5.4.0) 下有效(输出:Working)。

int main() {
    double val {0.0};
    string unit {" "};

    cout << "Enter a double value followed by a unit (cm , m, in, ft) with or without a space in between (followed by 'Enter'):\n";

    if (cin >> val)
    {
        cout << "Working val" << '\n';
        if (cin >> unit)
        {
            cout << "Working unit" << '\n';
        }
        else
        {
            cout << "Error unit" << '\n';
            auto f = cin.fail();
            auto b = cin.bad();
            cout << "f: " << f << ", b: " << b << '\n';
        }
    }
    else
    {
        cout << "Error val" << '\n';

        auto f = cin.fail();
        auto b = cin.bad();

        cout << "f: " << f << ", b: " << b << '\n';
    }

    return 0;
}

为什么 cin 在 Mac OS 下会进入不良状态?

下面是 Mac OS:

下的完整输出
Enter a double value followed by a unit (cm , m, in, ft) with or without a space in between (followed by 'Enter'):
10cm
Error val
f: 1, b: 0

Process finished with exit code 0

当我输入 10 cm(带有 space)时它正在工作:

Enter a double value followed by a unit (cm , m, in, ft) with or without a space in between (followed by 'Enter'):
10 cm
Working val
f: 0, b: 0
Working unit
f: 0, b: 0

Process finished with exit code 0

编辑:上一个(完整)问题:我正在尝试使用 C++ 进行编程原理与实践第 4 章的练习 7:

更改循环体,使其每次只读取一个 double。定义两个变量以跟踪您目前看到的最小值和最大值。每次通过循环写出输入的值。如果它是迄今为止最小的,请在数字后面写上迄今为止最小的。如果是迄今为止最大的,就在数字后面写上迄今为止最大的。

为每个输入的双数添加一个单位;即,输入 10cm、2.5in、5ft 或 3.33m 等值。接受四种单位:cm、m、in、ft。假设换算系数 1m == 100cm,1in == 2.54cm,1ft == 12in。将单位指示符读入字符串。您可以认为 12 米(数字和单位之间有 space)等同于 12 米(没有 space)。

#include "std_lib_facilities.h"

bool legalUnit(string unit)
{
    if (unit == "cm" || unit == "m" || unit == "in" || unit == "ft")
    {
        return true;
    }
    else {
        return false;
    }
}


int main() {
    bool first {true};
    double val {0.0};
    double smallest {0.0};
    double largest {0.0};
    string unit {" "};

    cout << "Enter a double value followed by a unit (cm , m, in, ft) with or without a space in between (followed by 'Enter'):\n";

    while (cin >> val >> unit)
    {

        if (legalUnit(unit))
        {
            cout << val << unit << '\n';

            if (first == true)
            {
                first = false;
                smallest = val;
                largest = val;
            }
            else if (val < smallest)
            {
                cout << " the smallest so far.\n";
            }
            else if (val > largest)
            {
                cout << " the largest so far.\n";
            }
        }
    }

    return 0;
}

程序在 mac 和 linux 上编译没有问题,输入一个数字后跟白色 space 和一个单位,例如 10 in 工作。

现在我的问题是: 在 mac 上,如果我输入例如 10in 程序会立即退出,因为 cin >> val >> unit returns假的。在 linux 上,相同的输入起作用,这意味着进入了循环。

关于编译器,我需要考虑什么吗?我在 Mac Mojave 10.14.5 和 Ubuntu 16.04.

中使用默认设置(自动检测编译器)的 CLion

mac 上的人可以确认 10cm 等输入不起作用吗?

这是 bug in libc++(2013 年的报告,我可能会补充)。

如果输入流中一个数字后跟一个字母,中间没有 space,那么读取这个数字可能会失败,也可能不会失败,具体取决于字母。 "bad" 字母是 A 到 F、I、N、P 和 X(以及对应的小写字母)。

聪明的reader会注意到那些正是可以组成十六进制常量的字母(是的,P是其中之一)以及单词NAN和INF。

其他表现相同的字符包括加号、减号和小数点(原因很明显)。