C++字符串输入缓冲区机制详解

 更新时间:2021年10月28日 15:50:20   作者:srymakerTT  
缓冲区是用来存放流中的数据,本文详细的介绍了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++实现数据文件存储与加载

    这篇文章主要为大家详细介绍了C++实现数据文件存储与加载,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • Clion-MinGW编译后的exe文件添加ico图标的操作方法

    Clion-MinGW编译后的exe文件添加ico图标的操作方法

    这篇文章主要介绍了Clion-MinGW编译后的exe文件添加ico图标的操作方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • C++之构造函数默认值设置方式

    C++之构造函数默认值设置方式

    这篇文章主要介绍了C++之构造函数默认值设置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • C++构造函数+复制构造函数+重载等号运算符调用

    C++构造函数+复制构造函数+重载等号运算符调用

    这篇文章主要介绍了C++构造函数+复制构造函数+重载等号运算符调用,文章叙述详细,具有一定的的参考价值,需要的小伙伴可以参考一下
    2022-03-03
  • C语言编程技巧 关于const和#define的区别心得

    C语言编程技巧 关于const和#define的区别心得

    尽量用const和inline而不用#define 这个条款最好称为:“尽量用编译器而不用预处理”,因为#define经常被认为好象不是语言本身的一部分。这是问题之一。再看下面的语句:
    2013-02-02
  • 简单介绍C++编程中派生类的析构函数

    简单介绍C++编程中派生类的析构函数

    这篇文章主要介绍了C++编程中派生类的析构函数,析构函数平时一般使用较少,需要的朋友可以参考下
    2015-09-09
  • c语言中&的用法示例代码

    c语言中&的用法示例代码

    这篇文章主要给大家介绍了关于c语言中&的用法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • C语言预处理预编译命令及宏定义详解

    C语言预处理预编译命令及宏定义详解

    这篇文章主要为大家介绍了C语言预处理预编译命令及宏定义的详解,其中包含运行环境命名约定条件及#under等基础详解,有需要的朋友可以借鉴参考下
    2021-10-10
  • 详谈全排列next_permutation() 函数的用法(推荐)

    详谈全排列next_permutation() 函数的用法(推荐)

    下面小编就为大家带来一篇详谈全排列next_permutation() 函数的用法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • c语言实现把文件中数据读取并存到数组中

    c语言实现把文件中数据读取并存到数组中

    下面小编就为大家带来一篇c语言实现把文件中数据读取并存到数组中。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12

最新评论