关于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 ...
随机推荐
- Bootstrap学习2--组件-列表组
备注:最新Bootstrap手册:http://www.jqhtml.com/bootstraps-syntaxhigh/index.html 1.列表组 列表组是Bootstrap框架新增的一个组件 ...
- LeetCode:字母异位词分组【16】
LeetCode:字母异位词分组[16] 题目描述 给定一个字符串数组,将字母异位词组合在一起.字母异位词指字母相同,但排列不同的字符串. 示例: 输入: ["eat", &quo ...
- 如何让Jackson JSON生成的数据包含的中文以unicode方式编码
我们都知道,Jackson JSON以高速.方便和灵活著称.之前的文章中介绍过使用注解的形式来规定如何将一个对象序列化成JSON的方法,以及如何将一个JSON数据反序列化到一个对象上.但是美中不足的一 ...
- django配置文件环境分离后celery的启动方式整理
django项目中,当配置文件分离时: 启动方式1: 硬编码写死在manage.py中: os.environ.setdefault("DJANGO_SETTINGS_MODULE" ...
- hbase shell-ddl(表定义指令)
hbase表定义指令详细解说篇 1. alter, alter_async, alter_status 2. create 3. describe (可以简写成'desc') 显示某张表的结构情况 ...
- B表中的pid对应A表中id,查询A表中数据,根据b表中对应a表中该id的数据数目排序
B表中的pid对应A表中id,查询A表中数据,根据b表中对应a表中该id的数据数目排序 select a.*,count(*) as c from a left join b on a.id=b.ai ...
- LINQ 学习路程 -- 查询操作 Deferred Execution of LINQ Query 延迟执行
延迟执行是指一个表达式的值延迟获取,知道它的值真正用到. 当你用foreach循环时,表达式才真正的执行. 延迟执行有个最重要的好处:它总是给你最新的数据 实现延迟运行 你可以使用yield关键字实现 ...
- jQuery绿色下拉网站导航
jQuery,下拉菜单,网站导航,绿色导航,菜单导航,jQuery绿色下拉网站导航是一款基于jquery实现的鼠标滑过下拉显示二级菜单. jquery特效代码:http://www.huiyi8.co ...
- Jquery 取值,赋值学习总结
<h2>获取和设置文本框值:</h2> <input type="button" value="赋值文件框" id="v ...
- c#基础综述
一个相关的博客:http://blog.csdn.net/zhang_xinxiu/article/details/8605980 很好的一个网站:http://www.runoob.com/