应使用std::getline读取整行字符串,因其可保留空格、制表符并读至换行符;若前有cin>>残留换行符,需先调用cin.ignore()清除;还可自定义分隔符,且比fgets更安全可靠。

用 std::getline 读取整行,别用 operator>>
默认的 operator>> 遇到空格、制表符或换行就停,所以 std::cin >> str 只能拿到第一个单词。真正要读带空格的字符串(比如用户输入“Beijing University”),必须换函数。
最直接的办法是 std::getline:
std::string s; std::getline(std::cin, s);
它会一直读到换行符为止,中间的空格、制表符全保留。注意:它不把换行符存进 s,但会把它从输入缓冲区里“吃掉”。
std::getline 前有残留换行符?先清缓冲区
常见坑:在 std::getline 前用了 std::cin >>(比如先读一个整数),这时输入缓冲区里还留着那个数字后的换行符,std::getline 一执行就立刻读到它,返回空字符串——看起来像“没输入”。
解决方法是手动跳过残留的换行符:
- 用
std::cin.ignore():默认跳过 1 个字符,通常够用 - 更稳妥写法:
std::cin.ignore(std::numeric_limits<:streamsize>::max(), '\n');</:streamsize>,跳过直到下一个'\n'
示例:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
int n; std::cin >> n; std::cin.ignore(); // 清掉换行 std::string s; std::getline(std::cin, s);
想按其他分隔符切分?传第三个参数
std::getline 不只认换行符。它的第三个参数可以指定任意 char 作为结束符,比如读到冒号就停:
std::string key, value; std::getline(std::cin, key, ':'); // 读到 ':' 停 std::getline(std::cin, value); // 再读后面的内容(含开头空格)
注意:分隔符本身不会被存入字符串,但后续输入仍从它之后开始。如果输入是 "name: Alice",key 是 "name",value 是 " Alice"(开头空格保留)。
用 C 风格 fgets?不推荐,除非对接旧代码
有人想到 fgets,它确实能读空格,但问题不少:
- 要自己管理字符数组大小,容易溢出
- 读入的字符串末尾带
'\n',得手动去掉 - 和
std::cin混用时缓冲区不同步,行为不可靠
C++ 场景下优先用 std::getline + std::string,内存安全、语义清晰。只有在必须填 C 接口(比如某些系统调用)时才考虑 fgets。
真正容易被忽略的是混合输入时的缓冲区残留——哪怕只多敲一次 std::cin >>,后面 std::getline 就可能失效。这点比语法本身更常导致调试半天。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










