关于cin
今天同学调试一个简单的程序的时候发现了问题,我们两个讨论的时候弄出了好多乐子
#include <iostream>
using namespace std;
int main()
{
;
cout << "c1=";
while (cin >> c1)
{
if ('y' == c1)
{
cout << "Good" << endl;
break;
}
else
cout << "Try again" << endl;
}
system("pause");
}
就是这个程序,其实很简单,同学测试的时候每次都是输入的25这样两个字符的数,导致每次打印两个Try again 而发给我测试的时候我都是用2这种一个字符的数
导致程序在我这里是正常的,到他那里就错了。。。。。其实重点是ci是一个字符类型的对象,而且cin是一个流,把键盘输入陆续输出到c1对象,所以25是字符'2'和'5',记录这个主要是告诉自己以后调试的时候要先用别人的测试用例,这样有助于快速定位到问题
----------------------------------------------------------以下为转载内容-------------------------------------------------------------------------------------------------------------
cin在你输入的时候,会跳过空白字符,它们会被放到缓冲区中,当你用接受空白字符的输入流时,这个时候从缓冲区(缓冲区实际上是队列)中获取到它们的
windows按下回车输入的是'\r' '\n'
int main()
{
]={};
]={};
cin >>buf1;
cin.getline(buf2,); // 这里似乎不等待输入
;
}
解决办法如下:
int main()
{
]={};
]={};
cin >>buf1;
cin.ignore(); // 或者 cin.sync(); 之类的
cin.getline(buf2,);
;
}
这是为什么呢?
因为,首先, Windows 上敲一下回车键,实质上是输入两个字符:回车符,紧跟着换行符。这两个字符的 ASCII 码分别为 0x0D 和 0x0A,一般来说,其C++转义表示分别为 '\r' 和 '\n'。然后,cin>> 默认是以一个或多个接连的白空格为间隔,cin.getline 默认则以单个换行符(0x0A)为间隔。回车符和换行符都属于白空格。
为了展示这个看不见的回车键敲击,用 istringstream 举个例子:
void disp(char *buf,int n)
{
;i<n;++i)
printf("0x%02X ",buf[i]);
printf("\n");
}
int main()
{
disp();
// 这相当于在控制台敲回车键,然后敲入s1,然后敲回车键,然后敲入s2
// 0x0D 0x0A 0x73 0x31 0x0D 0x0A 0x73 0x32 0x00
printf("\n");
{
istringstream iss("\r\ns1\r\ns2");
]={};
]={};
iss >>buf1;
iss >>buf2;
disp(buf1,); // 0x73 0x31 0x00 0x00 0x00
disp(buf2,); // 0x73 0x32 0x00 0x00 0x00
}
printf("\n");
{
istringstream iss("\r\ns1\r\ns2");
]={};
]={};
iss.getline(buf1,);
iss.getline(buf2,);
disp(buf1,); // 0x0D 0x00 0x00 0x00 0x00
disp(buf2,); // 0x73 0x31 0x0D 0x00 0x00
}
;
}
用 cin 的道理是一样的。区别在于相关的标准库函数会把 0x0D 转换为 0x0A,这就相当于回车键最终敲入缓冲区的是接连的两个换行符。由于这不影响讨论,下文还是用 0x0D 指代。
cin>> 每读到其所期待的东西后碰到 0x0D,就“断”一下,紧跟着的 0x0A 还在缓冲里。此时,如果改用 cin.getline() ,0x0A 立即被读入,而该间隔符前面没有字符,于是就有了 getline 已完成却没有 get 到 line 的错觉。而如果没有改用 cin.getline(),继续用cin>>,那么 cin>> 碰到紧跟着的 0x0A 时,这是在还没读到其所期待的东西就碰到了白空格,它的反应就是跳过该字符(这正是 cin.ignore(); 要做的),接着继续去读其所期待的东西。
关于cin的更多相关文章
- cin.ignore()函数的用法
cin.ignore(a,ch)方法是从输入流(cin)中提取字符,提取的字符被忽略(ignore),不被使用.每抛弃一个字符,它都要计数和比较字符:如果计数值达到a或者被抛弃的字符是ch,则cin. ...
- cin的使用问题
#cin的使用问题 cin输入类型不匹配的情况: #include<iostream> using namespace std; void main() { int i = 0; whil ...
- using namespace std 和 using std::cin
相较using std::cin使用using namespace std不会使得程序的效率变低,或者稳定性降低,只是这样作会将很多的名字引入程序,使得程序员使用的名字集合变小,容易引起命名冲突. 在 ...
- while(cin.eof)出错 poj
zoj遇到c++如何判定输入流结尾的问题,一不小心就超时了 楼下的代码可以通过zoj #include<iostream> using namespace std; int main(){ ...
- cin
cin 是预定义的标准输入流对象,cin 用来接收字符串时,遇“空格”.“TAP”.“回车”时都会结束.
- C++输入cout与输出cin
输入和输出并不是C++语言中的正式组成成分.C和C++本身都没有为输入和输出提供专门的语句结构.输入输出不是由C++本身定义的,而是在编译系统提供的I/O库中定义的.C++的输出和输入是用" ...
- cin, cin.getline等函数
char s[100]; cin>>s; // 输入一个字符串,遇“空格”.“TAB”.“回车”都结束 cin.getline(s, 20); // cin.get( ...
- strlen 字符型数组和字符数组 sizeof和strlen的区别 cin.get(input,Arsize)
strlenstrlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值 ...
- C++IO关于cin>>和getline的理解
这个问题困扰了我有一段时间了,趁着十一放假有时间,仔细研究了一下 首先来看一下输入输出运算符cin>>的构成:cin和>> cin>>是由两部分构成的,cin和&g ...
- 为什么可以用while(cin)?
为什么可以用while(cin)? /** * @brief The quick-and-easy status check. * * This allows you to write const ...
随机推荐
- git入门篇-----本地操作
一 ,git的简介 1 ,git的历史 概念性的知识,大家百度一下,就会出现好多优秀的文章供参考,这里我就不多说了. 如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好 ...
- 小程序getApp() 被删除坑
在一个非page的js文件内使用getApp,当前台切到后台的时候,定义的var app = getApp()被删除了 如:新建一个app-libs.js start: function() { va ...
- Kattis - horrorfilmnight 【贪心】
题意 有两个人想去一起看电影,然后分别给出两个人 分别喜欢看的电影都在哪些天 然后 同一个人 不能连续看两天他不喜欢的电影 求他们最多可以看多少次电影 思路 先将两人喜欢看的电影进行排序, ① 选择两 ...
- iOS tabbar 上面更换任意图
tabbar 对add 上面的图片 有一层默认虚化 对于这种系统高度继承后的 控件 处理办法就是自定义 解决方案 1.放在tabbar 上的图片 不能太小 不然裁剪后 会很模糊 2 .通过裁剪 压缩的 ...
- C#Winform之等待窗体
窗体主要代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ...
- P4773 红鲤鱼与绿鲤鱼
P4773 红鲤鱼与绿鲤鱼 暑假比赛的一个水题 总情况数:\(\dfrac{(a+b)!}{a!b!}\) 就是\(a+b\)条鲤鱼中选\(a\) or \(b\)的情况 反正我们会用完鲤鱼,则红鲤鱼 ...
- MapReduce修改输出的文件名
MapReduce默认输出的文件名称格式如下:part-r-00000 自定义名称,比如editName,则输出的文件名称为:editName-r-0000,此方法没有彻底修改整个文件名,只修改了一部 ...
- php设计模式课程---3、为什么会有抽象工厂方法
php设计模式课程---3.为什么会有抽象工厂方法 一.总结 一句话总结: 解决简单工厂方法增加新选择时无法满足面向对象编程中的开闭原则问题 1.什么是面向对象编程中的开闭原则? 应该对类的增加开放, ...
- 目标检测 — one-stage检测(二)
one-stage检测算法,其不需要region proposal阶段,直接产生物体的类别概率和位置坐标值,经过单次检测即可直接得到最终的检测结果,因此有着更快的检测速度,比较典型的算法如YOLO,S ...
- Tomcat翻译--Tomcat Web Application Deployment(Tomcat中部署web应用)
原文:http://tomcat.apache.org/tomcat-7.0-doc/deployer-howto.html Introduction(介绍) Deployment is the te ...