IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++字符串输入缓冲区机制 -> 正文阅读

[C++知识库]C++字符串输入缓冲区机制

一、缓冲定义

1.缓冲定义
缓冲是在两种不同速度设备之间传输信息时平滑传输过程的常用手段。
2.为什么引入缓冲区
操作系统这门课有明确的说明缓冲的作用,是为了解决高速设备和低速设备之间速度不匹配的问题,直接举个书上的CPU和打印机的例子:
首先我们要用打印机打印一篇文章肯定要经过CPU处理然后给到打印机打印文章,但是CPU处理1000个字节的文字一眨眼的事情,但是打印机可能需要若干秒,总不可能让CPU处理一个数据给打印机一个数据这样子等着运行,这就引入了缓冲区,CPU处理完数据存入缓冲区,打印机直接从缓冲区提取已经处理好的数据,这样子就解决了高速设备(CPU)和低速设备(打印机)处理速度不匹配的问题。

二、scanf,cin输入缓冲区

1.scanf和cin的缓冲类型
scanf和cin的缓冲类型为行缓冲,行缓冲的的特点是在输入数据只要没有碰到换行符(回车)就将数据存入输入缓冲区,当碰到换行符之后就将缓冲区中的数据取出使用。
2.scanf和cin的缓冲机制
scanf和cin输入数据缓冲机制基本一致,在读入一个数据时直到回车之前他都会存储在输入缓冲区中,直到碰到回车才会将数据从输入缓冲区中取出供变量使用,但是缓冲区中的换行符会被留在输入缓冲区中
3.cin.getline和cin.get
cin.get读取字符串直到读取到回车为止,但是也会将回车留在缓冲区。
cin.getline读取字符串直到读取到回车为止,但是不会讲回车留在缓冲区。
4.scanf和cin输入
※①cin和scanf读取一个字符的区别

	char c;
	cin>>c;//cin读取字符的时候不会读入空格、回车以及制表符,如果缓冲区开头是换行符或者制表符会被忽略并清除
	scanf("%c",&c);//scanf读取字符的时候不会管你是什么字符直接读进来

※②cin和scanf在读取缓冲区中的数字、字符串、浮点型的时候不会将开头的空格、换行符或者制表符当作数据读入,如果碰到了他们会将它们忽略并清除。需要注意cin.get和cin.getline不会将开头的空格、换行符或者制表符忽略并删除。

5.可能遇到的问题

①在用cin或者scanf读取一个字符串之后scanf再读取一个字符,发现读取的字符没办法输入而且输出了一个回车。看如下代码:

	char name[20];
    char c;
    cin>>name;
    cout<<name<<endl;
    scanf("%c",&c);
    cout<<"---"<<int(c)<<endl;

结果如下截图:
在这里插入图片描述
当我们输入name为123的时候程序就结束了输出c的值为10,在ASCII码编码中10对应的是换行符,为什么会出现上述这种情况呢?因为cin输入完之后将回车保留在了缓冲区中,而scanf("%c",&c)输入字符并不会判断是空格还是回车,直接将缓冲区中的回车拿了出来给了字符变量c。

②用cin.getline输入字符串之后再用scanf读取一个字符就和上面不一样了。看如下代码:

	char name[20];
    char c;
    cin.getline(name,20);
    cout<<name<<endl;
    scanf("%c",&c);
    cout<<"---"<<int(c)<<endl;

结果如下截图:
在这里插入图片描述
结果不同的原因是因为scanf,cin,cin.get在行缓冲取出数据之后会将换行符留在缓冲区中,然后再用scanf读入一个字符发现缓冲区并不为空就从缓冲区中将数据拿出来,而cin.getline会将缓冲区中的换行符也清除,所以不会有①这种情况出现。
③读入一个字符串之后后面的cin.get()一直无法读取数据,看如下代码:

	char name[20];
    cin.get(name,20);
    cout<<"--"<<name<<endl;
    cin.get(name,20);
    cout<<"--"<<name<<endl;
    cin.get(name,20);
    cout<<"--"<<name<<endl;
    cin.get(name,20);
    cout<<"--"<<name<<endl;
    cin.get(name,20);
    cout<<"--"<<name<<endl;

结果如下截图:
在这里插入图片描述
可以看到用第一个cin.get输入了数据之后后面的cin.get都无效了,这是因为cin.get从缓冲区中读取到换行符就结束并将换行符保留在缓冲区中,接下来的cin.get一直在缓冲区中碰到换行符就一直没有实际数据输入。
④整形和字符串混合输入
当先输入一个整形再用cin.getline输入字符串会发现没有经历输入字符串的过程,测试如下代码:

	char name[20];
    int a;
    cin>>a;
    cout<<a<<endl;
    cin.getline(name,20);
    cout<<"---"<<name<<endl;
    cout<<"end"<<endl;

结果如下:
在这里插入图片描述
根据上面的缓冲原理比较容易理解,cin输入一个整形后会在缓冲区中留下一个换行符,因为缓冲区中有换行符剩余,cin.getline从缓冲区中取出数据发现正好是换行符,那么就默认字符串输入完了,并将换行符从缓冲区中去掉,所以造成了上面的局面。

清除缓冲区

上面讲的问题基本上都是因为缓冲区中剩余的数据造成的,那么只需要有方法清除缓冲区就行了,可以用getchar(),cin.get()读取缓冲区中多的换行符。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-28 12:13:13  更:2021-10-28 12:14:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:32:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码