基础 - 字符读取函数scanf、getchar、gets、cin(清空缓存区解决单字符回车问题)
0x01 scanf、getchar、cin读取单字符:
如下:
//scanf读取字符 回车问题
void Sub_1_1()
{
char v1,v2;
scanf("%c", &v1);
scanf("%c", &v2);
printf("%d %d\n", v1, v2); //回车问题
} /* scanf()和getchar()函数是从输入流缓冲区中读取值的,
而并非从键盘(也就是终端)缓冲区读取。
而读取时遇到回车(\n)而结束的,这个\n会一起读入输入流缓冲区的,
所以第一次接受输入时取走字符后会留下字符\n,
这样第二次的读入函数直接从缓冲区中把\n取走了,显然读取成功了,
所以不会再从终端读取! */ //getchar读取字符 回车问题
void Sub_1_2()
{
char ch1, ch2;
ch1 = getchar();
ch2 = getchar();
printf("%d %d\n", ch1, ch2); //回车问题
} //cin读取单字符 无回车问题
void Sub_1_3()
{
char ch1, ch2;
cin >> ch1;
cin >> ch2; cout << ch1 << endl;
cout << ch2 << endl; }
例如:
Sub_1_1、Sub_1_2 输入 a,输出:

Sub_1_3输入a,输出:

为什么这个形式呢?
先说一下输入操作原理:程序的输入都建有一个缓冲区,即输入缓冲区。当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据。正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入,
这里的10恰好是回车符,scanf()和getchar()函数是从输入流缓冲区中读取值的,而并非从键盘(也就是终端)缓冲区读取。而读取时遇到回车(\n)而结束的,这个\n会一起读入输入流缓冲区的,所以第一次接受输入时取走字符后会留下字符\n,这样第二次的读入函数直接从缓冲区中把\n取走了。
0x02 scanf()和gets()读取字符串:
//scanf()读取字符串 空格问题
void Sub_2_1()
{
char str1[], str2[];
scanf("%s",str1);
printf("%s\n",str1);
scanf("%s",str2);
printf("%s\n",str2); //空格问题 //hello world ->
//hello
//world
/*第一次输入Hello world!后,
字符串Hello world!都会被读到输入缓冲区中,
而scanf()函数取数据是遇到回车、空格、TAB就会停止,
也就是第一个scanf()会取出"Hello",而"world!"还在缓冲区中,
这样第二个scanf会直接取出这些数据,而不会等待从终端输入。*/ //scanf()读取字符串会舍弃最后的回车符!
//hello ->
//hello -> } //gets()读取字符串 接受空格
void Sub_2_2()
{
char str1[], str2[];
gets(str1);
printf("%s\n",str1);
gets(str2);
printf("%s\n",str2); }
先来看Sub_2_1,程序的功能是读入一个字符串输出,在读入一个字符串输出。可我们会发现输入的字符串中不能出现空格,例如:

这个问题的原因跟0x01类似,第一次输入Hello world后,字符串Hello world都会被读到输入缓冲区中,而scanf()函数取数据是遇到回车、空格、TAB就会停止,也就是第一个scanf()会取出"Hello",而"world"还在缓冲区中,这样第二个scanf会直接取出这些数据,而不会等待从终端输入
Sub_2_2,gets不会有这个问题:

总结:
读取字符时:
scanf()以Space、Enter、Tab结束一次输入,不会舍弃最后的回车符(即回车符会残留在缓冲区中);
getchar()以Enter结束输入,也不会舍弃最后的回车符;
读取字符串时:
scanf()以Space、Enter、Tab结束一次输入
gets()以Enter结束输入(空格不结束),接受空格,会舍弃最后的回车符!
第二:为了避免出现上述问题,必须要清空缓冲区的残留数据,可以用以下的方法解决:
方法1:C语言里提供了函数清空缓冲区,只要在读数据之前先清空缓冲区就没问题了!
这个函数是fflush(stdin)。//似乎并没有用。
//setbuf(stdin, NULL);//使stdin输入流由默认缓冲区转为无缓冲区
方法2:自己取出缓冲区里的残留数据。
源代码(包括解决单字符回车问题):
#include <windows.h>
#include <IOSTREAM> using namespace std; void Sub_1_1();
void Sub_1_2();
void Sub_1_3(); void Sub_2_1();
void Sub_2_2(); int main ()
{
//scanf getchar
//Sub_1_1();
Sub_1_2();
//Sub_1_3(); /*****/
//scanf gets
// Sub_2_1();
//Sub_2_2();
} //setbuf(stdin, NULL);//使stdin输入流由默认缓冲区转为无缓冲区 //scanf读取字符 回车问题
void Sub_1_1()
{
char v1,v2; scanf("%c", &v1);
//setbuf(stdin, NULL); //解决回车问题
scanf("%c", &v2);
//setbuf(stdin, NULL); //解决回车问题
printf("%d %d\n", v1, v2); //回车问题
} /* scanf()和getchar()函数是从输入流缓冲区中读取值的,
而并非从键盘(也就是终端)缓冲区读取。
而读取时遇到回车(\n)而结束的,这个\n会一起读入输入流缓冲区的,
所以第一次接受输入时取走字符后会留下字符\n,
这样第二次的读入函数直接从缓冲区中把\n取走了,显然读取成功了,
所以不会再从终端读取! */ //getchar读取字符 回车问题
void Sub_1_2()
{
char ch1, ch2;
//setbuf(stdin, NULL); //解决回车问题
ch1 = getchar();
//setbuf(stdin, NULL); //解决回车问题
ch2 = getchar();
printf("%d %d\n", ch1, ch2); //回车问题
} //cin读取单字符 无回车问题
void Sub_1_3()
{
char ch1, ch2;
cin >> ch1;
cin >> ch2; cout << ch1 << endl;
cout << ch2 << endl; } //scanf()读取字符串 空格问题
void Sub_2_1()
{
char str1[], str2[];
scanf("%s",str1);
printf("%s\n",str1);
scanf("%s",str2);
printf("%s\n",str2); //空格问题 //hello world ->
//hello
//world
/*第一次输入Hello world!后,
字符串Hello world!都会被读到输入缓冲区中,
而scanf()函数取数据是遇到回车、空格、TAB就会停止,
也就是第一个scanf()会取出"Hello",而"world!"还在缓冲区中,
这样第二个scanf会直接取出这些数据,而不会等待从终端输入。*/ //scanf()读取字符串会舍弃最后的回车符!
//hello ->
//hello -> } //gets()读取字符串 接受空格
void Sub_2_2()
{
char str1[], str2[];
gets(str1);
printf("%s\n",str1);
gets(str2);
printf("%s\n",str2); } //总结
/*
读取字符时:
scanf()以Space、Enter、Tab结束一次输入,不会舍弃最后的回车符(即回车符会残留在缓冲区中);
getchar()以Enter结束输入,也不会舍弃最后的回车符;
读取字符串时:
scanf()以Space、Enter、Tab结束一次输入
gets()以Enter结束输入(空格不结束),接受空格,会舍弃最后的回车符!
第二:为了避免出现上述问题,必须要清空缓冲区的残留数据,可以用以下的方法解决:
方法1:C语言里提供了函数清空缓冲区,只要在读数据之前先清空缓冲区就没问题了!
这个函数是fflush(stdin)//似乎并没有用。
//setbuf(stdin, NULL);//使stdin输入流由默认缓冲区转为无缓冲区
方法2:自己取出缓冲区里的残留数据。
*/
基础 - 字符读取函数scanf、getchar、gets、cin(清空缓存区解决单字符回车问题)的更多相关文章
- 关于cin的缓存区影响效果
1. 当缓冲区中有残留数据时,cin函数会直接去读取这些残留数据而不会请求键盘输入.而且,回车符也会被存入输入缓冲区中. int num{}; while(cin>>num) cout&l ...
- UC编程:字符读取与行读取
字符读取函数的应用 下面的演示程序实现从/etc/passwd文件中提取用户名,打印到屏幕上并保存在copyname.txt文件中 使用的函数是getc().putc().putchar() [c] ...
- VBS基础篇 - 常用函数
Option Explicit '*********************************Date/Time函数******************************* 'CDate函 ...
- 深入了解scanf()/getchar()和gets()/cin等函数
转:http://www.cnblogs.com/FCWORLD/archive/2010/12/04/1896511.html 转:问题描述一:(分析scanf()和getchar()读取字符) s ...
- 深入了解scanf() getchar()和gets()等函数之间的区别
scanf(), getchar()等都是标准输入函数,一般人都会觉得这几个函数非常简单,没什么特殊的.但是有时候却就是因为使用这些函数除了问题,却找不出其中的原因.下面先看一个很简单的程序: 程序1 ...
- C语言初步学习I/O函数scanf、getchar、printf和putchar
scanf().printf().getchar()和putchar()这四个函数能够让用户和程序交流,所以被称为输入/输出函数,或简称为I/O函数. 这里先结合缓冲输入来讲讲scanf()和getc ...
- iOS 中基础字符判断函数收集(如判断大小写、数字等)
函数:isdigit 用法:#include 功能:判断字符c是否为数字 说明:当c为数字0-9时,返回非零值,否则返回零. 函数:islower 用法:#include 功能:判断字符c是否为小写英 ...
- PHP基础--strtr和str_replace字符替换函数
(一)strtr是字符替换函数 (1)单个字符替换: <?php echo strtr("abba", "ab", "10"),&qu ...
- scanf()/getchar()和gets()深入分析
C/C++学习笔记1 - 深入了解scanf()/getchar()和gets()等函数 ---------------------------------------------------- | ...
随机推荐
- zabbix3.4.7利用Windows性能监视器监控各项资源指标
zabbix自带的windows监控模板并没有监控windows cpu使用率的监控 在cmd命令的窗口输入perfmon,就会弹出一下界面 点击性能监视器 点击如图加号,出现很多参数 选择proce ...
- 移动应用调试之Inspect远程调试
移动应用调试之Inspect远程调试 一.准备工作 chrome浏览器,建议最新版本 如果你点击inspect打开的DevTools窗口一片空白,且刷新无效时,那极有可能是由于被墙的缘故. 二.Ins ...
- Json转换工具
import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterx ...
- 指导手册02:伪分布式安装Hadoop(ubuntuLinux)
指导手册02:伪分布式安装Hadoop(ubuntuLinux) Part 1:安装及配置虚拟机 1.安装Linux. 1.安装Ubuntu1604 64位系统 2.设置语言,能输入中文 3.创建 ...
- python笔记10-切片(从list或字符串中取几个元素)
name1 = 'zcl,pyzyz'names = ['zcl','py','zyz'] #切片的意思就是从list里面或者字符串里面取几个元素#切片操作对字符串也是完全适用的 # print(na ...
- 使用GraphHttpClient调用Microsoft Graph接口 - GET
博客地址:http://blog.csdn.net/FoxDave 使用GraphHttpClient类调用Microsoft Graph REST API,你可以使用GET,POST和PATCH请求 ...
- keil的51项目创建
keil的51项目创建步骤: 工程创建: Project->New uVision Project 项目命名:如...test CPU->Atmel::AT89C51 文件创建: File ...
- 安装软件碰见error2502 2503
把鼠标放到Win8屏幕的最左下角,等待Win8 Metro界面的缩略图出现后点击鼠标右键,在弹出的菜单中选择“命令提示符(管理员)” 打开的“命令提示符(管理员)” 找到自己将要安装的程序路径 ...
- SQL注入之Sqli-labs系列第三十六关(基于宽字符逃逸GET注入)和三十七关(基于宽字节逃逸的POST注入)
0X1 查看源码 function check_quotes($string) { $string= mysql_real_escape_string($string); return $string ...
- vim分屏操作
启动分屏 1.使用大写O参数进行垂直分屏 $ vim -On file1 file2 ... 2.使用小写o参数进行水平分屏 $ vim -on file1 file2 ... 注: n是数字,表示分 ...