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(清空缓存区解决单字符回车问题)的更多相关文章

  1. 关于cin的缓存区影响效果

    1. 当缓冲区中有残留数据时,cin函数会直接去读取这些残留数据而不会请求键盘输入.而且,回车符也会被存入输入缓冲区中. int num{}; while(cin>>num) cout&l ...

  2. UC编程:字符读取与行读取

    字符读取函数的应用 下面的演示程序实现从/etc/passwd文件中提取用户名,打印到屏幕上并保存在copyname.txt文件中 使用的函数是getc().putc().putchar() [c] ...

  3. VBS基础篇 - 常用函数

    Option Explicit '*********************************Date/Time函数******************************* 'CDate函 ...

  4. 深入了解scanf()/getchar()和gets()/cin等函数

    转:http://www.cnblogs.com/FCWORLD/archive/2010/12/04/1896511.html 转:问题描述一:(分析scanf()和getchar()读取字符) s ...

  5. 深入了解scanf() getchar()和gets()等函数之间的区别

    scanf(), getchar()等都是标准输入函数,一般人都会觉得这几个函数非常简单,没什么特殊的.但是有时候却就是因为使用这些函数除了问题,却找不出其中的原因.下面先看一个很简单的程序: 程序1 ...

  6. C语言初步学习I/O函数scanf、getchar、printf和putchar

    scanf().printf().getchar()和putchar()这四个函数能够让用户和程序交流,所以被称为输入/输出函数,或简称为I/O函数. 这里先结合缓冲输入来讲讲scanf()和getc ...

  7. iOS 中基础字符判断函数收集(如判断大小写、数字等)

    函数:isdigit 用法:#include 功能:判断字符c是否为数字 说明:当c为数字0-9时,返回非零值,否则返回零. 函数:islower 用法:#include 功能:判断字符c是否为小写英 ...

  8. PHP基础--strtr和str_replace字符替换函数

    (一)strtr是字符替换函数 (1)单个字符替换: <?php echo strtr("abba", "ab", "10"),&qu ...

  9. scanf()/getchar()和gets()深入分析

    C/C++学习笔记1 - 深入了解scanf()/getchar()和gets()等函数 ---------------------------------------------------- | ...

随机推荐

  1. php7 数据导出Excel office 2011中文乱码问题

    public function test(){ $data = array( array( 'name' => '对对对', 'score' => 80, 'grade' => '急 ...

  2. asp.net数据加载进度和模态窗口的完美打开,而且窗口不被阻止

    采用jquery的技术打开模态窗口,效果肯定不错,但是微软的asp.net ajax就无法用了,例如updatepanel面板和updateprogress就看不到效果,也就是jquery与asp.n ...

  3. CSS 选择器 选择 拥有多个类名 的元素

    今天开发的时候,碰到这个连起来的类名. 才想起来,这个类似于 <div class="node hide"></div> 连起来写,表示找到  拥有这两个类 ...

  4. bzoj2190

    题解: 显然当坐标不互质的时候 是可以看得见的 所以线性筛选欧拉函数 代码: #include<bits/stdc++.h> using namespace std; ; int n,an ...

  5. oracle项目案例脚本

    前言:这是我从其他地方找到的一个oracle的案例脚本,在自己使用数据库的时候方便使用. -- 01 创建表空间 -- 注意表空间的路径 根据实际安装环境进行调整 CREATE TABLESPACE ...

  6. 表单验证,添加动态class

  7. Java容器解析系列(3) List AbstractList ListIterator RandomAccess fail-fast机制 详解

    做为数据结构学习的常规,肯定是先学习线性表,也就是Java中的List,开始 Java中List相关的类关系图如下: 此篇作为对Java中相关类的开篇.从上图中可以看出,List和AbstractLi ...

  8. jmeter接口测试基础知识1.0

    jmeter:性能测试工具,压测测试计划右键--添加--Threads(Users)--线程组(线程数就是并发数)--右键线程组--添加--Sampler--HTTP请求--最上面的名称可以修改,就是 ...

  9. GitHub入门与实践 读书笔记一:欢迎来到GitHubde世界

    1.什么是GitHub GitHubshi为开发者提供Git仓库的托管服务.除此之外,还为开发者提供能帮助提高代码效率和品质的功能. GitHub和Git的区别? Git是源码仓库而GitHub是在网 ...

  10. selenium+grid做分布式测试

    一.grid介绍 1.本文用的是selenium-server-standalone-3.8.1.jar 2.Firefox用的55版本和对应的驱动 二.grid使用流程说明比如有个A机器,作用是hu ...