写什么代码来清空缓冲区

news/2024/11/8 18:46:01/文章来源:https://www.cnblogs.com/hisun9/p/18535641

在 C++ 中,清空输入缓冲区的方法主要用于清除 std::cin 输入流中的残留字符,避免它们影响后续的输入操作。下面介绍几种常用的办法。

1. cin.ignore() 方法

cin.ignore() 是最常用的清空缓冲区方法,可以忽略输入流中的若干字符。

  • cin.ignore(numeric_limits<streamsize>::max(), '\n');:

    • 忽略缓冲区中的所有字符,直到遇到换行符 \n

    • numeric_limits<streamsize>::max() 设置了一个非常大的忽略字符数,以确保足够多的字符被忽略。

    • 举一个例子

    #include <iostream>
    #include <limits> // 用于 numeric_limits
    using namespace std;int main() {char ch;cout << "请输入一个字符: ";cin >> ch;// 清空缓冲区cin.ignore(numeric_limits<streamsize>::max(), '\n');string line;cout << "请输入一行文字: ";getline(cin, line);cout << "您输入的字符是: " << ch << endl;cout << "您输入的行是: " << line << endl;return 0;
    }
    

    输出如下:

    img

    插一句题外话:

    如果不加cin.ignore(numeric_limits<streamsize>::max(), '\n');这句的话,输出会是这样的:

    img

    原因:

    在输入一个字符输入步骤中,cin >> ch; 会读取用户输入的一个字符,但它只读取一个字符的内容,用户在输入字符后可能还按了“回车键” (Enter),这会留在输入缓冲区里。如果不清空缓冲区,后续调用 getline(cin, line); 时,会直接读取缓冲区中残留的“回车”,导致 line 获得一个空字符串,无法读取到用户实际输入的内容。

    再附上c++_primer上的一段话来帮助理解:

    img

  • cin.ignore(1, '\n');:

    • 忽略一个字符(如换行符)。适用于需要跳过单个字符的情况。

    • 常用于输入特定字符后直接忽略后面的一个换行符。

2. cin.clear() 和 cin.sync()

在某些情况下,除了 cin.ignore() 外,还可能需要用 cin.clear()cin.sync(),尤其当 cin 的错误标志被设置时:

  • cin.clear();:

    • 清除 cin 的错误标志(如输入不符合期望的数据类型)。

      在这篇博客cin和scanf的返回值知多少提到过一点 cin 的错误标志。

    • 如果 cin 发生输入错误(如输入字符到整数变量),会设置错误标志,需要使用 cin.clear() 清除。

    • 清除错误标志后再配合 cin.ignore(),可以清空错误输入,并让 cin 恢复正常工作。

  • cin.sync();:

    • 清除输入缓冲区中所有内容。

    • 在某些编译器中,它可以立即清空缓冲区,但在一些平台上不一定完全可靠。

  • 举一个例子

    #include <iostream>
    using namespace std;int main() {int num;cout << "请输入一个整数: ";cin >> num;if (cin.fail()) {// 清除错误标志并清空缓冲区cin.clear();cin.ignore(numeric_limits<streamsize>::max(), '\n');cout << "输入无效,请重新输入一个整数。" << endl;}return 0;
    }
    

    输出如下:

    img

插一句题外话

对于上面这个例子,当我改成如下代码:

#include <iostream>
using namespace std;int main() {int num;cout << "请输入一个整数: ";cin >> num;if (cin.fail()) {// 清除错误标志并清空缓冲区cin.clear();//cin.ignore(numeric_limits<streamsize>::max(), '\n');cout << "输入无效,请重新输入一个整数。" << endl;}char ch = cin.get();cout << "ch: " << ch << endl;return 0;
}

输出如下:

img

看了这个输出情况应该更能体会到cin.ignore(numeric_limits<streamsize>::max(), '\n');的作用了。

然后又试着改成这样:

#include <iostream>
using namespace std;int main() {int num;cout << "请输入一个整数: ";cin >> num;//if (cin.fail()) {//    // 清除错误标志并清空缓冲区//    cin.clear();//    cin.ignore(numeric_limits<streamsize>::max(), '\n');//    cout << "输入无效,请重新输入一个整数。" << endl;//}char ch = cin.get();cout << "ch: " << ch << endl;return 0;
}

输出如下:

img

在这种情况下,输出为“乱码”是因为当 cin >> num; 读取无效输入(字母 a)时,cin 会进入失败状态(即 fail 状态),并设置错误标志。由于 cin 处于失败状态,接下来的 cin.get() 也无法正常读取字符。

在失败状态下,cin.get() 不会从输入缓冲区中读取任何有效的字符,因此 ch 变量未被正确赋值,而是包含了一个未定义的值。这就是导致输出“乱码”或一个不可见字符的原因。

3. 使用 while (cin.get() != '\n'); 清除缓冲区

这是一个循环方法,用于逐个读取并丢弃缓冲区中的字符,直到遇到换行符。

  • while (cin.get() != '\n');:

    • 使用 cin.get() 读取每个字符,直到换行符结束。

    • 适合当不确定输入缓冲区有多少残留字符时,可以完全清空缓冲区。

  • 举一个例子:

    #include <iostream>
    using namespace std;int main() {char ch;cout << "请输入一个字符: ";cin >> ch;// 手动逐个读取并丢弃直到换行符while (cin.get() != '\n');string line;cout << "请输入一行文字: ";getline(cin, line);cout << "您输入的字符是: " << ch << endl;cout << "您输入的行是: " << line << endl;return 0;
    }
    

    输出如下:

    img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/828958.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[ACTF2020 新生赛]BackupFile 1

[ACTF2020 新生赛]BackupFile 1 打开实例,显示Try to find out source file!(尝试找出源文件!)dirsearch扫描,发现flag页面以及备份文件泄露wget下载并打开index.php.bak,发现flag.php的源码这边要求参数key为数值的同时又要==123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w…

【架构】异地多活架构设计

一、关于基础架构二、关于异地多活三、写时延是关键3.1 核心在于数据层的写操作3.2 写时延在跨城时发生质变3.3 同步复制缩短距离降目标3.4 异步复制就近分片做有损四、写量大拆分片五、做隔离拆分片六、其他影响因素6.1 读时延可就近6.2 读量大扩副本6.3 连接多加代理七、数据…

1.11--04:网线主管

http://noi.openjudge.cn/ch0111/04/网线主管 思路题目要求保留小数点后两位,说明啥,如果我们要循环找答案,每次只能+0.01,不然容易错过答案,看这个数据范围,一看就炸了考虑到二分怎么分?众所周知,二分的前提条件是内容必须有一定的规律如果当前导线和除以中间长度(我们…

【MySQL】数据库备份详解

一、引言1.1 数据库备份的重要性二、MySQL数据库备份的基础知识2.1 备份类型2.2 备份工具与方法三、MySQL数据库备份的实施步骤3.1 环境准备3.2 选择合适的备份工具与方法3.3 执行备份3.4 验证备份3.5 存储与管理备份四、MySQL数据库恢复流程4.1 mysqldump备份的恢复4.2 物理备…

关于虚拟仿真云实验教学_解决方案及优势介绍!

在科技飞速演进的潮流下,虚拟仿真技术正不断蓬勃发展,成为教育领域的一颗耀眼之星。作为创新的教育手段,虚拟仿真云教学正逐渐受到越来越多教育机构的高度重视与广泛应用,本文将为您详细探讨虚拟仿真云实验教学的解决方案及其所带来的多重优势。在科技飞速演进的潮流下,虚…

08C++选择结构(2)——教学

一、逻辑变量 教学视频 存储类似灯亮或灯灭、是男还是女等结果只有两种可能的数据时,可以使用逻辑型变量。 逻辑型变量用关键字bool定义,所以又称为布尔变量,其值只有两个false(假)和true(真),false和true是逻辑常量,又称布尔常量。 流程图如下:英汉小词典: bool:布…

我的二次元相册又回来了

从最早的图库,到图床,在到现在的相册.我对图片的执着已经可以说是跨越了好几个世纪了. 图库的图片是存在七牛云的,后来流量被刷就关闭了. 图床,现在转为为博客提供图片上传服务了. 相册,就是手机中相册的概念,它既可以存图片也可以放视频. 逐渐是越来越完善了 这两天就把平常保…

劫持微信聊天记录并分析还原 —— 合并解密后的数据库(三)

程序以 Python 语言开发,可读取、解密、还原微信数据库并帮助用户查看聊天记录,还可以将其聊天记录导出为csv、html等格式用于AI训练,自动回复或备份等等作用。本工具设计的初衷是用来获取微信账号的相关信息并解析PC版微信的数据库。程序以 Python 语言开发,可读取、解密、…

ABC377

C link存一下那些点不能占,用总数减去即可,注意存的时候可以用一个\(map\),存过的就不要再存了。

新配置!米尔新唐MA35D1核心板512M DDR配置发布!

米尔在2024年8月推出了基于新唐MA35D1芯片设计的嵌入式处理器模块MYC-LMA35核心板及开发板。MA35D1是集成2个Cortex-A35与1个Cortex-M4的异构微处理器芯片。核心板采用创新LGA 252PIN设计,原生17路UART和4路CAN FD等丰富的通讯接口,可广泛应用于新能源充电桩、工程机械控制器…

将本地nuget包推送到Nexus

1.安装nuget.exe ,下载地址https://www.nuget.org/downloads,下载后直接将nuget.exe拷贝到C:\Windows\System32目录下2.cmd执行 nuget setapikey e500146f-8594-32a3-9041-6ad7d2bf8d9b -source http://192.168.10.22:8081/repository/nuget-hosted/ 为仓库设置apikey3.执行…