scanf函数具体解释与缓冲区
1.基本信息
函数原型:
int scanf( char *format, args, ...);
函数返回值:
读入并赋给args的数据个数。遇到文件结束返回EOF,出错返回0。
函数功能:
scanf函数是格式化输入函数,它从标准输入设备(键盘)读取输入的信息。按format指定的格式输入数据给args所指向的内存单元。
调用格式:
scanf("格式控制字符串",地址表);
int a, b;
scanf("%d%d",&a,&b);//输入10 12
当中格式控制串由三类字符构成:格式化说明符、空白符、非空白符
1 格式化说明符
%c 读入一个字符
%d 读入十进制整数
%f 读入一个浮点数
%o 读入一个八进制整数
%x 读入十六进制整数
%s 读入一个字符串
%p 读入一个指针
%[] 扫描字符集合,输入的字符属于方括号内字符串中某个字符。则提取该字符,否则结束提取
%[^] 扫描字符集合。输入的字符属于属于方括号内字符串中的某个字符,结束提取
2 空白字符
空白字符会使scanf()函数在读取操作时略去输入中的一个或多个空白字符,空白字符能够是space,tab,newline,直到第一个非空白字符出现为止。
之所以被称为空白字符是由于它们被打印出来时,在页面上出现的是空白而不是各种记号。
3 非空白字符
非空白字符会使scanf()函数在读取时剔除与之同样的非空白字符。
2. scanf函数的注意事项
1. scanf函数中"格式控制"的后面应该是变量地址。
2. 假设在“格式控制”字符串中除了格式说明符还有其他字符。则在输入数据时在相应的位置输入与之同样的字符。
3. 在用“%c”格式输入字符时。空白字符(space,tab,newline)和“转义字符”都作为有效字符输入。
4. 在用“%s”格式输入字符时,输入的字符串中含有空白字符(space,tab,newline)。字符串读取结束。
5. 在输入数据时。遇到下面情况时觉得该数据结束。
(1) 遇到space。newline,Tab键;
(2) 按指定的宽度输入;
(3) 遇到非法输入;
3 清除键盘缓冲区
键盘缓冲区,是计算机输入过程重要环节。它是一个环形队列。用来暂时保存从键盘输入的字符。共32字节。
补充说明:
‘Enter回车键’包括1个字符是‘\r’’;
方法1:
int c;
while ( ( c = getchar() ) != '\n' && c!= EOF)
{
;
}
不停的使用getchar()获取缓冲区字符,直到获取的字符是换行符'\n'或文件结尾EOF为止,这种方法能够完美清除输入缓冲区,而且具备可移植性。
方法2:
fflush( stdin );刷新标准输入缓冲区,也就是丢弃缓冲区中的内容。(非标准)
4 错误案例分析
4.1 參数输入不匹配
int data = -1; while (1)
{
printf("1:\n2:\n3:\n4:\n0:\ninput sever:");
scanf("%d",&data);//输入不是整数data值不改变 switch (data)
{
case 1: printf("1\n");break;
case 2: printf("2\n");break;
case 3: printf("4\n");break;
case 0: break;
default: printf("default\n");
} if (data == 0)
{
break;
}
}//end of while
问题:
当不小心输入了一个字符。而不是数据时。程序进入死循环。不断输入printf函数的内容。
分析:
因为scanf("%d",&data)要求參数是个整数,而实际输入却为字符,參数不匹配scanf结束data的输入。
函数继续运行。
当再次运行到scanf函数时。此时输入缓冲区中有内容。直接从缓存中读取不再等待人为输入。故出现死循环。屏幕不再有等待输入提示。
办法:
在scanf函数后加入fflush(stdin)就能够解决这个问题了。
由于每次输入数据时缓冲区都被刷新,每次都会等待输入。
4.2 scanf输入中不能有空格的问题
char str[80];
scanf("%s",str);
printf("str = %s\n", str);
问题:
当输入的字符中有空格时,输出不完整。
分析:
%s格式字符遇到空格时结束读取。兴许的字符不再读取储存。
办法1:
scanf函数改写为:scanf("%[^'\n']",str);
办法2:
使用gets函数,关于gets函数见:gets()函数具体解释与缺陷
4.3 %c和缓冲区问题
char str[5]; for(int i = 0; i < 4; i++)
{
scanf( "%c",&str[i]);
} str[4] = '\0';
printf("str:%s\n",str);
问题:
当输入a回车b回车。函数运行结束。
分析:
因为scanf按%c格式输入,当输入a并按回车时输入缓冲区中的内容是'a'和'\r',分别给了str[0]和str[1]。相同输入b时也是如此。刚好4个字符结束输入。
str字符数组的内容各自是'a'、'\r'、'b'、'\r'、'\0'。
办法1:
在scanf函数后面加入语句:fflush(stdin);
办法2:
使用gets函数。
scanf函数具体解释与缓冲区的更多相关文章
- C语言scanf函数详细解释
原文链接 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准 ...
- C语言scanf函数详细解释(转载)
原文地址:https://blog.csdn.net/21aspnet/article/details/174326 scanf 函数名: scanf 功 能: 执行格式化输入 用 法: int sc ...
- scanf函数读取缓冲区数据的问题
标准I\O的缓冲类型 标准I\O根据不同的应用需求,提供了全缓冲.行缓冲.无缓冲三种缓冲方式. 全缓冲:只有当划定的缓冲区被填满或者数据读取至末尾时,才开始执行I\O操作(执行系统提供的read\wr ...
- scanf函数与输入缓冲区
本文链接:http://www.cnblogs.com/xxNote/p/4008668.html 今天看书的时候遇到scanf函数与缓冲区的问题,产生了一些猜想即:应该有一个指针来记录缓冲区中读取到 ...
- scanf()函数释疑(word找的,没源地址了)
scanf()函数释疑(上) 一.序言 scanf()函数的控制串的使用 例1. #include "stdio.h" int main(void) { int a,b,c; sc ...
- Scanf函数输入字符串
Scanf函数输入字符串 #define _CRT_SECURE_NO_WARNINGS //#pragma warning(disable:4996) #include <stdio.h> ...
- [转载]VS2012编译C语言scanf函数error的解决方法
在VS 2012 中编译 C 语言项目,如果使用了 scanf 函数,编译时便会提示如下错误: error C4996: 'scanf': This function or variable may ...
- scanf()函数用法小结
scanf()函数是格式化输入函数,它从标准输入设备(键盘) 读取输入的信息. 其调用格式为: scanf("<格式化字符串>",<地址表>); ...
- c语言学习之基础知识点介绍(三):scanf函数
本节继续介绍c语言的基础知识点. scanf函数:用来接收用户输入的数据. 语法:scanf("格式化控制符",地址列表); 取地址要用到取地址符:&(shift+7) 例 ...
随机推荐
- Plain Old Data (POD)
Plain Old Data (POD) POD指的是这样一些数据类型:基本数据类型.指针.union.数组.构造函数是 trivial 的 struct 或者 class. POD用来表明C++中与 ...
- unity学习笔记1--Space Shooter
其实我一直觉得我是个模棱两可的人,就计算机这块来说,自己还是想制作游戏什么的,但是又得考虑到现实就业的问题,所以现在自己主要在学安卓和javaweb.现在大概是心血来潮吧,突然想追逐下自己的理想,虽然 ...
- 手工安装kubernetes
参考的URL是 http://www.cnblogs.com/zhenyuyaodidiao/p/6500830.html 安装kubernets本身比较顺利,只是作dashboard时,老是日文版, ...
- 跨机房openvpn互联
实现目标:北京的client能访问上海的client (1)vpn server配置 1)基本配置 关闭selinux sed -ri '/^SELINUX=/cSELINUX=disabled' / ...
- zookeeper与activemq整合
(1)zookeeper与activemq原理 使用ZooKeeper实现的Master-Slave实现方式,是对ActiveMQ进行高可用的一种有效的解决方案,高可用的原理:使用ZooKeeper( ...
- 关闭浏览器session就被干掉的假象的问题
当在前台取出session时,关闭浏览器后再次访问服务器,这时服务器返回了一个null,此时的返回的session并非之前的那个session而是一个新的session. -->先来看看sess ...
- JDBC连接池(数据源)
自定义连接池:用装饰设计模式将原连接的close方法改造成将连接还回数据源:装饰设计模式:http://www.cnblogs.com/tongxuping/p/6832518.html: 开源数据库 ...
- [转]认识session
今天想用一个session来实现用户登录判断,也算是对之前session的探究,查了下资料session的运行机制如下: session是服务器端的一种会话机制,当客户端的请求服务器创建一个sessi ...
- (12)python 标准库
模块 如果模块和自己写的程序不在同一个目录,可以通过sys.path.append(路径)把程序引入 import sys sys.path.append('C:/abc')#注意 \ 的方向 意思是 ...
- hdu6058
hdu6058 题意 定义 \(f(l, r, k)\) 函数为区间 \([l, r]\) 第 \(k\) 大的数,如果 \(r - l + 1 < k\),\(f = 0\) .求 \(\su ...