cin>>读不到空格是设计行为,因默认以空白符分隔;读整行需用getline()或cin.getline(),注意缓冲区大小、failbit处理及混合输入时的状态干扰。
默认情况下 cin >> 遇到空格、制表符或换行就停止读取,只拿到第一个单词。这不是 bug,是设计行为——它面向「格式化输入」,比如读数字、单个单词。
如果你要读一整行(含空格),必须换方法:
std::cin.getline():最常用,读固定长度的 C 风格字符串(char[])std::getline()(带 std::string):更安全、推荐,自动管理内存cin.get() 或 cin.ignore():常用来清理残留换行符,否则 getline() 可能直接读到空行cin.getline() 原型是:istream& getline(char* s, streamsize n, char delim = '\n')。注意它不返回 string,而是操作原始字符数组。
容易出错的地方:
n 必须比实际最大输入多 1(留位置给结尾的 '\0'),写成 char buf[100]; cin.getline(buf, 100); 才安全;写成 101 就越界了failbit 置位(后续 cin >> 会失效),需手动调用 cin.clear() 恢复'\n'),但不会把它存进 buf;这点和 gets() 不同,也更安全char name[50]; std::cout << "Enter your full name: "; std::cin.getline(name, 50); // 安全:最多读49字符 + '\0' std::cout << "Hello, " << name << "!\n";
绝大多数场景下,你应该优先用 std::getline(std::cin, str),它接受 std::string&,自动扩容,不用操心长度和内存。
但要注意一个经典坑:如果之前用了 cin >>(比如读了个 int),输入缓冲区里还剩一个换行符,getline() 会立刻读到它,返回空字符串。
cin >> 后加 cin.ignore() 清掉残留换行cin.ignore() 默认只忽略 1 个字符;若不确定前面有多少空白,可写成 cin.ignore(std::numeric_limits<:streamsize>::max(), '\n');
getline() 读输入,再用 std::stoi() / std::stod() 解析数字int age; std::string line; std::cin >> age; // 输入 25 后敲回车,'\n'留在缓冲区 std::cin.ignore(); // 忽略一个字符(即那个 '\n') std::getline(std::cin, line); // 这才真正读下一行
这是最隐蔽也最容易被忽略的问题:输入流的状态(如 failbit、eofbit)是全局的。一次失败的 cin.getline() 或超长输入会让整个 cin 失效,后续所有读取都会跳过。
判断是否出错很简单:
if (!std::cin) 或 if (cin.fail()) 可检测错误cin.clear() 清标志位,再 cin.ignore(...) 清缓冲区cin.good() 判断“还能不能用”,它太严格;用 cin >> x 或 getline() 的返回值判断更直接真正麻烦的是没人告诉你:你改了 cin 的格式标志(比如

cin.setf(ios::hex)),它会一直生效,直到你手动切回来。