为什么看起来 cin 将我的双精度输入转换为整数? C++
Why does it look like that cin converts my double input into integer? C++
我有以下代码:
//...
int variable_1, variable_2;
cout << "Please enter the 2 numbers: ";
try
{
if ( !(cin >> variable_1) ) throw Invalid_number(); //empty class just for exceptions
if ( !(cin >> variable_2) ) throw Invalid_number(); //problem is here.
}
catch (Invalid_number) {cerr << "You must enter integers\n"; return -1;}
//...
因此,如果我为 variable_1 输入整数并为 variable_2 输入双精度数,程序不会抛出异常,它只是继续执行程序的其余部分。从调试中我看到,当我输入双 variable_2 即 2.4 时,它只是将其转换为 2 并且不会引发异常。相反,如果我为 variable_1 输入一个双精度数,它会抛出异常,它会被捕获并且程序结束 (return -1)。有谁知道为什么会发生这种情况以及如何让它在每次输入的两个数字中的任何一个不是 int 时抛出异常?
当您使用 std::istream
读取 int
时,它首先跳过前导 space,然后尝试读取符号(如果有 none,则假定为正) , 后跟一串数字。一旦没有更多数字,它就会停止读取。如果至少可以读取一个数字并且数字序列与符号相结合产生值,则读取成功。否则读取失败。
在你的第一种情况下,第一个值被完全读取,然后是一个读取,留下小数点 .
和它后面的任何内容未读。但是,读取都成功了。
在第二种情况下,读取小数点前的数字,将小数点留在流中。第二次读取尝试读取 int
但找不到小数点。
如果有其他原因使读取失败有点棘手,因为不清楚哪些输入应该失败!您可以在读取后检查下一个字符是否为预期字符,例如白色 space。 ...或者您可以阅读该行的其余部分并验证它是否只包含 whitespaces:这将是在格式化和未格式化之间切换而没有任何读取的罕见情况之一是正确的做法.
通过覆盖 std::num_get<...>
方面的相应 do_get()
成员并安装一个 std::locale
对象,该对象在找到预期失败案例之一时失败 int
可能会失败。不过,我怀疑这比这里的合理要复杂一些。
我有以下代码:
//...
int variable_1, variable_2;
cout << "Please enter the 2 numbers: ";
try
{
if ( !(cin >> variable_1) ) throw Invalid_number(); //empty class just for exceptions
if ( !(cin >> variable_2) ) throw Invalid_number(); //problem is here.
}
catch (Invalid_number) {cerr << "You must enter integers\n"; return -1;}
//...
因此,如果我为 variable_1 输入整数并为 variable_2 输入双精度数,程序不会抛出异常,它只是继续执行程序的其余部分。从调试中我看到,当我输入双 variable_2 即 2.4 时,它只是将其转换为 2 并且不会引发异常。相反,如果我为 variable_1 输入一个双精度数,它会抛出异常,它会被捕获并且程序结束 (return -1)。有谁知道为什么会发生这种情况以及如何让它在每次输入的两个数字中的任何一个不是 int 时抛出异常?
当您使用 std::istream
读取 int
时,它首先跳过前导 space,然后尝试读取符号(如果有 none,则假定为正) , 后跟一串数字。一旦没有更多数字,它就会停止读取。如果至少可以读取一个数字并且数字序列与符号相结合产生值,则读取成功。否则读取失败。
在你的第一种情况下,第一个值被完全读取,然后是一个读取,留下小数点 .
和它后面的任何内容未读。但是,读取都成功了。
在第二种情况下,读取小数点前的数字,将小数点留在流中。第二次读取尝试读取 int
但找不到小数点。
如果有其他原因使读取失败有点棘手,因为不清楚哪些输入应该失败!您可以在读取后检查下一个字符是否为预期字符,例如白色 space。 ...或者您可以阅读该行的其余部分并验证它是否只包含 whitespaces:这将是在格式化和未格式化之间切换而没有任何读取的罕见情况之一是正确的做法.
通过覆盖 std::num_get<...>
方面的相应 do_get()
成员并安装一个 std::locale
对象,该对象在找到预期失败案例之一时失败 int
可能会失败。不过,我怀疑这比这里的合理要复杂一些。