cin >> 默认跳过前导空白符(空格、制表符、换行),读取到下一个空白符为止;对char不跳空白,读带空格字符串需用getline,混合使用时需注意缓冲区残留。

cin >> 默认就跳过空格,但只跳开头的
绝大多数情况下,cin >> 读取 int、double、string 等内置类型时,**自动跳过输入流开头连续的空白符(空格、制表符、换行)**,然后读到下一个空白符为止。这不是“跳过所有空格”,而是“跳过前导空白 + 以空白为分隔符截断”。
常见误解是以为它会把整个输入里的空格都过滤掉——其实不会。比如输入 " 123 456 ",cin >> x 只读出 123,剩下 " 456 " 还在缓冲区里。
- 对
int/double:跳过前导空白,读数字直到非数字字符(含空格/换行) - 对
std::string:跳过前导空白,读非空白字符直到下一个空白 - 对
char:不跳空白!cin >> c会把空格、换行都当作有效字符读入
想读带空格的字符串?别用 >>,改用 getline
cin >> 遇到空格就停,所以没法读 "hello world" 这种含空格的整行。这时候必须换函数:
用 std::getline(cin, s) —— 它读一整行(包括中间空格),直到遇到换行符,并把换行符从缓冲区丢弃。
立即学习“C++免费学习笔记(深入)”;
- 注意:如果前面刚用过
cin >>读数字,缓冲区可能还剩一个换行符,getline会立刻读到空行。得先调cin.ignore()清掉它 -
getline不跳前导空白;如果输入是" abc def \n",读出来就是" abc def "(前后空格保留) - 如果只想去掉前后空格,得手动 trim,C++20 没原生
trim,得自己写或用find_first_not_of+find_last_not_of
想逐字符读且跳过所有空白?用 cin.peek() + ignore() 或自定义循环
如果目标是“忽略所有空白字符,只处理非空白字符”,cin >> 对 char 不适用(它不跳空格),得手动控制:
char c;
while (cin.peek() == ' ' || cin.peek() == '\t' || cin.peek() == '\n') {
cin.ignore();
}
cin >> c; // 此时 c 是第一个非空白字符
更通用的做法是写个循环跳过所有 std::isspace 成立的字符:
-
#include后用std::isspace(static_cast判断(注意类型转换,避免负值问题)(cin.peek())) - 直接用
cin >> std::ws也能跳前导空白:它是个输入操纵符,效果等价于跳过所有前导空白符 - 但
std::ws不吃掉后续非空白字符,只是“推进到第一个非空白位置”,之后仍需cin >> c或cin.get(c)来读
容易被忽略的坑:混合 >> 和 getline 时的缓冲区残留
这是最常踩的坑。比如:
int n; cin >> n; string line; getline(cin, line); // 这里 line 很可能为空!
因为 cin >> n 读完数字后,回车键产生的 '\n' 还留在缓冲区,getline 立刻读到它并停止,返回空串。
- 修复方式:在
getline前加cin.ignore(1, '\n')(忽略最多 1 个字符,直到遇到换行)或更稳妥的cin.ignore(std::numeric_limits<:streamsize>::max(), '\n') - 或者统一用
getline读所有输入,再用std::stringstream解析数字,彻底避开缓冲区混乱 - 另一个陷阱:
cin >>失败(如输入字母却读int)会导致流进入failbit状态,后续所有读取都失败,得调cin.clear()+cin.ignore(...)清理
空白符处理看着简单,但混合使用不同读取方式时,缓冲区状态才是真正的复杂点。









