为何C++读取无效流输入时,整数被设为0而非保留初始值?
问题原因
你的问题核心在于C++标准版本带来的行为差异:
- 你参考的《Programming: Principles and Practice Using C++》可能基于C++03及更早标准编写。在旧标准中,当输入流读取算术类型(比如
int)失败时,目标变量的值会保持初始化时的状态(也就是你的代码里的-1)。 - 而在C++11及之后的标准中,规定当
>>操作符读取算术类型失败时,会将目标变量赋值为0,不管它之前有没有被初始化。GCC和Clang现在默认启用C++11及以上标准,所以你看到age变成0而不是保持-1。
具体到你的测试场景:当你先输入年龄(数字)再输入姓名时,first_name会读取这个数字(因为string可以接受任意非空白字符序列),接下来cin尝试把姓名(字符串)读取到age(int类型),这显然会失败。此时按照C++11+标准,age会被置为0,而非保留初始的-1。
如何让行为符合书中描述
如果你想让代码保持书中的预期行为(输入失败时age保留-1),可以在输入后检查流的状态,若失败则手动恢复age的初始值:
#include <iostream> #include <string> #include <limits> using namespace std; int main() { cout << "Please enter your first name and age\n"; string first_name = "???"; int age = -1; cin >> first_name >> age; // 检查输入是否失败 if (!cin) { age = -1; // 恢复初始值 cin.clear(); // 清除流的错误状态 cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 跳过缓冲区中的无效内容 } cout << "Hello, " << first_name << "(age" << age << ")\n"; }
补充说明
输入流失败后,流的状态会被标记为failbit,此时后续的输入操作都会被跳过,直到你调用cin.clear()清除错误状态,并用ignore()跳过缓冲区里的无效内容。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

