C语言中关于scanf读取缓存区的问题

目录
  • 前言
  • scanf函数的定义
  • 功能:执行格式化输入
  • 总结
  • 解决方法

前言

在牛客做了很多坑爹的题,明明代码没问题但是就退无法AC,看了很多题解之后,发现是scanf读取缓存区,在输入输出时出现了问题 于是写个博客总结一下

首先我们要了解什么是 scanf 函数

根据 cplusplus.com的解释

scanf函数的定义

scanf()函数是通用 终端格式化输入 函数,它从标准输入设备(键盘)
读取输入的信息。可以读入任何固有类型的数据并自动把数值变换成适当的机内格式。 其调用格式为:
scanf("<格式化字符串>",<地址表>);

功能:执行格式化输入

并且注意:scanf()函数返回成功赋值的数据项数,出错时则返回EOF。

当进一步深挖之后(暂时不需要知道原理,只需要知道结果即可),
可以得到这样一个认识:
键盘输入的东西并没有直接给scanf读取 而是在缓冲区进行暂时存放
比如这样一段代码:

#include <stdio.h>
int main()
{
int a, b, c, d, e;
scanf("%d %d %d %d", &a, &b, &c, &d);
printf("%d %d %d %d\n", a, b, c, d);
scanf("%d", &e);
printf("%d\n", e);
return 0;
}

预期:1 2 3 4

​ 1 2 3 4

​ 5

​ 5

但是如果你这样输入: 1 2 3 4 5

会输出 1 2 3 4

​ 5

这是因为scanf以回车键为信号,去缓冲区进行读取数据,只要数据的格式符合标准,那么就可以正确读取,否则就要等待继续输入/读取失败

总结

通过查阅网站我们知道了,scanf函数是标准输入流(从键盘接收数据),接收的数据放入输入缓冲区中,其中就包括在键盘输入的空格、回车这类字符,

但是!!!

当你用%d接收时是不会影响的,但是用%c就会产生错误,这是因为在"%c"输入时,空格和转义字符均被视为有效字符会被%c接收。从而导致输出错误,无法AC

解决方法

1.List item

可以再%c前 键入一个空格 (优解)

eg:scanf(" %c",&a);

这里 %c前面加上空格键 可以消除前面所有的空白字符(输入的时候就会消化掉这个\n) 从而 不需要使用getchar()去吞\n

并且不会为下次留下空白字符的隐患

2.使用getchar()去吞掉缓存区中的\n

while(ch=getchar()!=EOF)

​		getchar();

使用getchar(); 去吞掉缓存区中剩余的 ‘\n' ,从而使程序可以正常运行

到此这篇关于C语言中关于scanf读取缓存区的问题的文章就介绍到这了,更多相关C语言scanf缓存区内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 浅析C语言中sscanf 的用法

    名称:sscanf() - 从一个字符串中读进与指定格式相符的数据. 复制代码 代码如下: 函数原型:Int  sscanf( string str, string fmt, mixed var1, mixed var2 ... );int scanf( const char *format [,argument]... ); 说明:sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源.其中的format可以是一个或多个 {%[*] [wi

  • C语言中fgets和fscanf区别详解

    C语言中fgets和fscanf区别详解 一.作用上的大概区别: ①fgets:从文件中读取一行数据存入缓冲区(fgets遇到回车才会结束,不对空格和回车做任何转换就录入到缓冲区,结束后再往缓冲区写多一个\0,所以它是读一行数据) ②fscanf:从文件中读取一段数据存入缓冲区(fscanf遇到空格或回车就结束,它会把空格或回车转换为\0,所以它是读一小段数据) 二.举个例子:把a.txt文件中的内容复制到b.txt. a.txt中的内容(第一行中"我爱你小白"和"开玩笑&q

  • 解决C语言中使用scanf连续输入两个字符类型的问题

    昨天用C编程,遇到一个关于scanf的细节问题,假如运行如下程序: #include<stdio.h> int main() { char ch1,ch2; printf("Input for ch1:/n"); scanf("%c",&ch1); printf("ch1=%c/n",ch1); printf("Input for ch2:/n"); scanf("%c",&ch

  • c语言获取用户输入字符串是scanf和gets的区别详解

    解释 gets(s)函数与 scanf("%s",&s) 相似,但不完全相同,使用scanf("%s",&s) 函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止. 1.scanf() 所在头文件:stdio.h 语法:scanf("格式控制字符串",变量地址列表); 接受字符串时:scanf("%s",

  • C语言 scanf输入多个数字只能以逗号分隔的操作

    C之scanf输入多个数字只能以逗号分隔,而不能用空格 TAB空白符分隔 #include <stdio.h> int main() { int num_max(int x,int y,int z); int a,b,c,max; scanf("%d,%d,%d",&a,&b,&c); max=num_max(a,b,c); printf("max=%d",max); return 0; } int num_max(int x,i

  • C语言清除scanf()缓存的案例讲解

    又重新过一遍C语言,感觉每次重学C语言都有不同的感受,遇到了一个问题,就是scanf()这个问题,其实细究起来,也有很多可以值得深挖的,实际上每次细细的挖掘的话,都是对C语言的更透彻的认识. 那么下面我就对scanf()中清除输入缓冲区的方法讲解: 应用场景:我们使用多个scanf()的时候,如果输入缓冲区还有数据的话,那么scanf()就不会询问用户输入,而是直接就将输入缓冲区的内容拿出来用了,这就导致了前面的错误影响到后面的内容,为了隔离这种问题, 总的思想:通过各种方法将输入缓冲区的内容读

  • c语言 sscanf,scanf,fscanf正则表达式用法

    每种语言都对正则表达式有着不同程度的支持,在C语言中,有输入功能的这三个函数对正则表达式的支持并不强大,但是我们还是有必要了解一下. 首先来看看他们的原型: #include <stdio.h> int scanf(const char *format, ...); int fscanf(FILE *stream, const char *format, ...); int sscanf(const char *str, const char *format, ...); 均可以接受变参,ss

  • C语言中关于scanf读取缓存区的问题

    目录 前言 scanf函数的定义 功能:执行格式化输入 总结 解决方法 前言 在牛客做了很多坑爹的题,明明代码没问题但是就退无法AC,看了很多题解之后,发现是scanf读取缓存区,在输入输出时出现了问题 于是写个博客总结一下 首先我们要了解什么是 scanf 函数 根据 cplusplus.com的解释 scanf函数的定义 scanf()函数是通用 终端格式化输入 函数,它从标准输入设备(键盘) 读取输入的信息.可以读入任何固有类型的数据并自动把数值变换成适当的机内格式. 其调用格式为: sc

  • 一文带你掌握Go语言中的文件读取操作

    目录 os 包 和 bufio 包 os.Open 与 os.OpenFile 以及 File.Read 读取文件操作 bufio.NewReader 和 Reader.ReadString 读取文件操作 小结 os 包 和 bufio 包 Go 标准库的 os 包,为我们提供很多操作文件的函数,如 Open(name) 打开文件.Create(name) 创建文件等函数,与之对应的是 bufio 包,os 包是直接对磁盘进行操作的,而 bufio 包则是带有缓冲的操作,不用每次都去操作磁盘.

  • C语言中输入函数(scanf()、fgets()和gets())的区别详解

    前言 大家都知道在C语言中,有三种主要的输入函数:scanf(),fgets()以及gets().他们的使用方法及注意事项如下: 1.scanf() 它是一种格式化的输入方式,可一次性按照规定的格式输入多个数据域. scanf函数是一个标准库函数,它的函数原型在头文件"stdio.h"中.与printf函数相同,C语言也允许在使用scanf函数之前不必包含stdio.h文件. scanf函数的一般形式为: scanf("格式控制字符串", 地址表列); 其中,格式控

  • C语言中关于scanf函数的一些问题详解

    在学习创建二叉树时遇到了scanf的一些问题,在此记录下来 创建根节点A后理想情况是输入A的左子树,若不为空继续创建左子树,但输入A后发现重复创建了一个左子树,测试后发现输入A换行后scanf函数接收了换行符(ASCII码10) 若想按次序创建各个节点则需要使用getchar()吸收换行符 不接收换行符也可以输入一个完整的二叉树序列,也可以成功创建. void CreateBiTree(BiTree &T) { char ch, temp; scanf("%c", &c

  • Node.js基础入门之缓存区与文件操作详解

    目录 缓存区 1. 什么是缓存区? 2. 创建指定长度的缓存区 3. 通过数组创建缓存区 4. 通过字符串创建缓存区 5. 读写缓存区 6. 复制缓存区 文件操作 1. 异步直接读取 2. 同步直接读取 3. 流式读取 4. 写入文件 5. 流式写入文件 6. 读取文件信息 7. 删除文件 8. 管道 9. 链式流 经过前面三天的学习,Node.js的基础知识已逐渐掌握,今天继续学习缓存区和文件操作,并稍加整理加以分享,如有不足之处,还请指正. 缓存区 1. 什么是缓存区? JavaScript

  • 详解C语言中的内存四区模型及结构体对内存的使用

    内存四区 1.代码区 代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的. 2.静态区 所有的全局变量以及程序中的静态变量都存储到静态区. 3.栈区 栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出.对于自动变量,什么时候入栈,什么时候出栈,是不需要程序控制的,由C语言编译器.实现栈不会很大,一般都是以K为单位的. 当栈空间以满,但还往栈

  • 从C语言中读取Python 类文件对象

    问题 你要写C扩展来读取来自任何Python类文件对象中的数据(比如普通文件.StringIO对象等). 解决方案 要读取一个类文件对象的数据,你需要重复调用 read() 方法,然后正确的解码获得的数据. 下面是一个C扩展函数例子,仅仅只是读取一个类文件对象中的所有数据并将其输出到标准输出: #define CHUNK_SIZE 8192 /* Consume a "file-like" object and write bytes to stdout */ static PyObj

  • Java语言中&&与& ||与|的区别是什么

    1.运算符两边的变量为boolean变量时 先列出代码: public class Test { public static void main(String[] args) { boolean a = false; boolean b = true; if (a && b) { // do something System.out.println("a&&b"); } if (a & b) { // do something System.ou

  • C语言中输入输出流与缓冲区的深入讲解

    前言 缓冲区 又称为缓存,它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区. 缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区. 原理介绍: 当调用输入函数scanf()时,输入函数会将我们输入的数字输入到输入缓冲区, 而当我们的输入缓冲区有内容时,再次输入将不会被执行, 而是直接跳过执行,将输入缓冲区的内容赋给变量; 1.为什么要引入缓冲区 例如,我们从磁盘里取信息,我们先把读出的数据放在缓

随机推荐