在学习完C语言之后学习C++,最先碰到的不同点就是最基本的输入输出,cin与cout和printf与scanf的机制完全不同。下面简单讲解cin与cout,仅用于初步理解。
CIN
输入机制
不同于scanf,在敲键盘输入的时候,内容不会直接给到变量,而是先储存在输入缓冲区里,只有按下回车,缓冲区才会把数据交给cin处理。
这种输入方式导致在字符串输入的时候会有一个缺陷。
字符串输入的缺陷
char name[20];
cin >> name;
然后输入
Chao空格Sheng回车
就像我们说的,这一行会先存储到缓存区中,然后cin再进行读取,存到字符数组中。
而当我们输出的时候,cout在读取字符数组的时候,他知道读到\0的时候结束。
但是cin在读取缓存区的时候,我们无法输入\0这个字符,缓存区无法出现空字符。那怎么判断字符串的结束呢,cin会使用空白(空格,制表符,换行符)来确定字符串的结束。
这意味着cin在获取字符数组输入的时候只读取一个单词。读取后放到数组中,我们输出的时候屏幕上只会打印Chao这个单词。
要将整条短语而不是一个单词作为字符串输入,需要采用另一种字符串的读取方法,也就是面向行而不是单词的方法,好消息是,cpp中提供了这样的函数,详情见我的上一篇文章。
cin优先吃缓冲区的残留字符:
就像刚才说的,连续多行的cin都会首先在cin的缓冲区中寻找剩下的内容来进行输入,而不会让你再输入东西,除非缓存区没东西了。
另外,后面的cin在遇到空白(空格,回车,制表符)时会跳过,然后寻找内容输入,直到遇到下一个空白。
cin的一个隐患
当你使用cin时,输入内容,然后回车,这个回车换行符会保存在缓存区成为一个隐患
如果你紧接着使用getline(cin,str),那么getline会直接读到回车,导致getline什么都得不到。
COUT
机制
相同于cin,cout也有缓存区,需要输出的内容先存在缓存区中,当遇到可以刷新缓存区的操作时,cout才会将内容打印在屏幕上。
这个操作就好像,我有一个仓库(缓存区),我cout就是在向仓库中放包裹,只有下达相关命令之后,存储的快递才会向外派送,清空仓库。
如果不碰到这样的命令,则程序会一直执行下去,一直得不到输出,也就是说在内容打印到屏幕之前,程序可能已经做了很多工作。
而像这样的命令有:
- endl
很多人刚开始学习cpp的时候都会对endl的换行机制产生疑惑,他不同于\n。 endl会先输出换行\n,在强制调用flush刷新缓冲区,立刻把内容全部打印到屏幕上。
- 遇到cin输入(两个缓存区有同步机制,cin缓存区使用的时候会自动刷新cout缓存区)ps:这个同步机制可以被关掉
- 程序结束return 0;
- 手动刷新cout.flush();
以上只是cin和cout的简单逻辑,在实际运用中会有很多细节和方法需要注意,以后我学到的时候会更深入地讲解。