为什么C++中cin与getline两种输入方式的读取行为存在差异?
C++中cin和getline的输入行为差异及底层逻辑
你观察到的行为差异本质是C++标准中「格式化输入运算符>>(即常用的cin >>写法)」和「getline非格式化输入函数」对分隔符的处理规则完全不同,具体底层逻辑和对应现象解释如下:
1 格式化输入(cin >>)的分隔符处理规则
cin >> 属于面向类型匹配的格式化输入函数,处理流程固定为:
- 启动读取时自动跳过输入缓冲区开头的所有空白字符(包括空格、换行符
\n、制表符\t等),直到碰到第一个非空白字符才正式开始读取内容 - 持续读取内容直到碰到下一个空白字符就停止,此时碰到的空白字符不会被从缓冲区取走,会留在当前游标位置等待后续输入函数读取
2 getline的分隔符处理规则
getline属于逐行读取的非格式化输入函数,处理流程固定为:
- 不会主动跳过任何开头字符,从当前游标位置直接开始读取
- 持续读取内容直到碰到换行符
\n就停止,此时碰到的\n会被从缓冲区中取走丢弃,游标自动移动到\n的下一位,且读取到的最终内容不会包含这个\n
3 三个示例的行为对应解释
示例1:连续两次使用cin >>
string a, b; cin >> a; cin >> b; cout << a << "-" << b << endl; // 输入: "cat\nhat" // 输出: "cat-hat"
第一次cin >> a读取到cat后碰到\n停止,\n留在缓冲区。第二次cin >> b启动时先自动跳过开头的\n,从下一位的h开始读取hat,因此最终输出为cat-hat。你之前认为是第一次cin移动游标跳过\n属于认知偏差,实际是第二次cin主动跳过了开头的空白字符。
示例2:cin >>混合getline
string a, b; cin >> a; getline(cin, b); cout << a << "-" << b << endl; // 输入: "cat\nhat" // 输出: "cat-"
第一次cin >> a读取cat后,缓冲区当前游标位置是\n。getline不会跳过开头的字符,直接从\n开始读取,碰到\n就停止,读取到空内容存入b,同时把\n丢弃,游标移动到下一位的h,因此最终输出为cat-。
示例3:连续两次使用getline
string a, b; getline(cin, a); getline(cin, b); cout << a << "-" << b << endl; // 输入: "cat\nhat" // 输出: "cat-hat"
第一次getline从开头读取到\n为止,把cat存入a,同时丢弃\n,游标移动到下一位的h。第二次getline从h开始读取到下一个换行(或输入结束),把hat存入b,因此输出为cat-hat。
内容的提问来源于stack exchange,提问作者Jeremy Fisher
相关产品推荐
相关产品推荐

