Windows 上 cin>> 与 cin.getline() 混用的问题
2012-11-26 20:55
393 查看
经常看到类似下例的问题:
而解决办法如下:
这是为什么呢?
因为,首先, Windows 上敲一下回车键,实质上是输入两个字符:回车符,紧跟着换行符。这两个字符的 ASCII 码分别为 0x0D 和 0x0A,一般来说,其C++转义表示分别为 '\r' 和 '\n'。然后,cin>> 默认是以一个或多个接连的白空格为间隔,cin.getline
默认则以单个换行符(0x0A)为间隔。回车符和换行符都属于白空格。
这里不讨论为什么 Windows 上敲回车键会输入这两个字符,以及这两个字符本来应该对应什么动作(如果存在“本来应该”这么一说的话)。
为了展示这个看不见的回车键敲击,用 istringstream 举个例子:
用 cin 的道理是一样的。区别在于相关的标准库函数会把 0x0D 转换为 0x0A,这就相当于回车键最终敲入缓冲区的是接连的两个换行符。由于这不影响讨论,下文还是用 0x0D 指代。
cin>> 每读到其所期待的东西后碰到 0x0D,就“断”一下,紧跟着的 0x0A 还在缓冲里。此时,如果改用 cin.getline() ,0x0A 立即被读入,而该间隔符前面没有字符,于是就有了 getline 已完成却没有 get 到 line 的错觉。而如果没有改用 cin.getline(),继续用cin>>,那么 cin>> 碰到紧跟着的 0x0A 时,这是在还没读到其所期待的东西就碰到了白空格,它的反应就是跳过该字符(这正是
cin.ignore(); 要做的),接着继续去读其所期待的东西。
int main() { char buf1[5]={0}; char buf2[5]={0}; cin >>buf1; cin.getline(buf2,5); // 这里似乎不等待输入 return 0; }
而解决办法如下:
int main() { char buf1[5]={0}; char buf2[5]={0}; cin >>buf1; cin.ignore(); // 或者 cin.sync(); 之类的 cin.getline(buf2,5); return 0; }
这是为什么呢?
因为,首先, Windows 上敲一下回车键,实质上是输入两个字符:回车符,紧跟着换行符。这两个字符的 ASCII 码分别为 0x0D 和 0x0A,一般来说,其C++转义表示分别为 '\r' 和 '\n'。然后,cin>> 默认是以一个或多个接连的白空格为间隔,cin.getline
默认则以单个换行符(0x0A)为间隔。回车符和换行符都属于白空格。
这里不讨论为什么 Windows 上敲回车键会输入这两个字符,以及这两个字符本来应该对应什么动作(如果存在“本来应该”这么一说的话)。
为了展示这个看不见的回车键敲击,用 istringstream 举个例子:
void disp(char *buf,int n) { for(int i=0;i<n;++i) printf("0x%02X ",buf[i]); printf("\n"); } int main() { disp("\r\ns1\r\ns2",9); // 这相当于在控制台敲回车键,然后敲入s1,然后敲回车键,然后敲入s2 // 0x0D 0x0A 0x73 0x31 0x0D 0x0A 0x73 0x32 0x00 printf("\n"); { istringstream iss("\r\ns1\r\ns2"); char buf1[5]={0}; char buf2[5]={0}; iss >>buf1; iss >>buf2; disp(buf1,5); // 0x73 0x31 0x00 0x00 0x00 disp(buf2,5); // 0x73 0x32 0x00 0x00 0x00 } printf("\n"); { istringstream iss("\r\ns1\r\ns2"); char buf1[5]={0}; char buf2[5]={0}; iss.getline(buf1,5); iss.getline(buf2,5); disp(buf1,5); // 0x0D 0x00 0x00 0x00 0x00 disp(buf2,5); // 0x73 0x31 0x0D 0x00 0x00 } return 0; }
用 cin 的道理是一样的。区别在于相关的标准库函数会把 0x0D 转换为 0x0A,这就相当于回车键最终敲入缓冲区的是接连的两个换行符。由于这不影响讨论,下文还是用 0x0D 指代。
cin>> 每读到其所期待的东西后碰到 0x0D,就“断”一下,紧跟着的 0x0A 还在缓冲里。此时,如果改用 cin.getline() ,0x0A 立即被读入,而该间隔符前面没有字符,于是就有了 getline 已完成却没有 get 到 line 的错觉。而如果没有改用 cin.getline(),继续用cin>>,那么 cin>> 碰到紧跟着的 0x0A 时,这是在还没读到其所期待的东西就碰到了白空格,它的反应就是跳过该字符(这正是
cin.ignore(); 要做的),接着继续去读其所期待的东西。
相关文章推荐
- C++ 输入函数 cin>>、cin.getline()和cin.get()区别
- C++中cin.get(),cin.getline(),cin>>,gets(),cin.clear()使用总结
- cin>>,cin.get(),cin.getline()的一些用法
- C++ 输入函数 cin>>、cin.getline()和cin.get()区别
- YUM安装遇到问题:File"/usr/bin/yum", line 29, in <module> File"/usr/share/yum-cli/yummain.py", line 276, in
- while(cin>>str)无法结束的问题
- C++中cin和cin.getline函数连用的问题
- cin<<,cin.get(),cin.getline()等区别与联系
- C++中cin>> cin.get(char[], int) cin.getline(char[], int) cin.get(char)输入区别
- C++中cin.get(),cin.getline(),cin>>,gets(),cin.clear()使用总结
- 针对表单的get提交与超链接中<a></a>乱码问题
- &quot;cin&gt;&gt;&quot; &quot;get()&quot; &quot;getline()&quot;比较
- C++ 输入函数 cin>>、cin.getline()和cin.get()区别
- while(cin>>str)无法结束的问题
- C++ cin>> cin.get() cin.getline()
- C++ Primer 关于while(cin>>word) 退出循环问题
- 从cin>>ch, cin.get(ch)看C++的参数引用
- windows下的txt文件传到Linux下中文乱码问题 <转>
- 解决cin.getline()未经输入就结束的问题
- C++中while(cin>>str)和while(cin.get(str))的结束问题