c语言scanf中的分隔符的作用,C语言中scanf与分隔符(空格回车Tab)-程序员宅基地

技术标签: c语言scanf中的分隔符的作用  

众所周知,C语言中的scanf函数的作用是从标准输入设备(通常是键盘)读取输入值,并存储到参数列表中指针所指向的内存单元。下面从几个方面说一下一些稍微细节的东西。下面的实验都在vc6.0中通过。

1、scanf的返回值

scanf通常返回的是成功赋值(从标准输入设备赋值到参数列表所指定的内存区域)的数据项数,如果出错或是遇到end of file(注意,如果想从键盘输入EOF,在windows的DOS窗口用Ctrl+Z 或F6;在UNIX系统上,用CTRL+D。),则返回EOF,比如:

scanf("%d%d", &x, &y);

如果x和y都被成功读入,那么scanf的返回值就是2;

如果只有x被成功读入,返回值为1;

如果x和y都未被成功读入,返回值为0;

如果遇到错误或遇到end of file,返回值为EOF。

2、scanf的处理机制

scanf以删除的方式从缓冲区读入数据(来自标准输入设备的数据存储在缓冲区),也就是说,scanf从缓冲区读入一个数据项,该数据项在缓冲区中就被清除掉了。而如果scanf需要读取一个数据项,返现缓冲区当前是空的,那么程序就会在scanf代码处阻塞,等待用户输入,scanf函数接收到相应的数据项之后,在缓冲区中将这一数据项清除,scanf函数返回,程序继续执行。

3、scanf对不同类型输入的处理方式

首先,要清除一个概念:空白字符(white space)。一般,程序中所指的空白字符是指空格(space),回车(enter)和指标符(table)。

3.1 整数%d

对于整型数据的输入,也就是说"%d"类型的输入,scanf默认的分割符是所有的空白字符(空格,回车和指标符都行)。也就是说如果一个scanf函数中出现scanf("%d%d",&a,&b),那么用任何一个空白字符来分隔两个整数a,b的值,变量a,b都可以接收到正确的输入。另外,要注意的是,scanf对于数字输入,会忽略输入数据项前面的空白字符。下面是例1:

Code:

#include

intmain()

{

inta,b;

printf("Input the value of a and b:");

while(scanf("%d%d",&a,&b)!=EOF)

{

printf("a=%d,b=%d\n",a,b);

printf("Input the value of a and b:");

}

return0;

}

Output:

Input the value of a and b:123 456

a=123,b=456

Input the value of a and b:123  456

a=123,b=456

Input the value of a and b:123

456

a=123,b=456

Input the value of a and b:

123 456

a=123,b=456

Input the value of a and b:     123 456

a=123,b=456

Input the value of a and b: 123 456

a=123,b=456

Input the value of a and b:^Z

Press any key to continue

3.2 字符串%s

scanf对于字符串输入的处理和对整数类似,会忽略前导的空白字符,而且默认的分隔符是所有的空白字符。但是,要注意的是,由于C语言中,没有string类型,都是用char型数组来表示。因此,scanf会为每一个输入的字符串最后加一个‘\0’。下面是一个例子,可以看出scanf这货的边界控制还是要小心。如下例2。

#include

intmain()

{

chara[5],b[5];

inti;

printf("Input the value of a and b:");

while(scanf("%s%s",a,b)!=EOF)

{

printf("a=%s,b=%s\n",a,b);

for(i=0;i<5;i++)

printf("%d:(%c) ",a[i],a[i]);

printf("\n");

for(i=0;i<5;i++)

printf("%d:(%c) ",b[i],b[i]);

printf("\n");

printf("Input the value of a and b:");

}

return0;

}

运行结果:

0818b9ca8b590ca3270a3433284dd417.png

3.3 字符%c

scanf在处理对字符数据的输入时,既不会忽略前导空白字符,默认也没有任何分隔字符。所有的字符,包括空白字符都会被当成输入字符。下面是例3。

#include

intmain()

{

chara ,b ;

printf("Input the value of a and b:");

while(scanf("%c%c",&a,&b)!=EOF)

{

printf("a=%c,b=%c\n",a,b);

printf("Input the value of a and b:");

}

return0;

}

运行结果:

0818b9ca8b590ca3270a3433284dd417.png

可以看出,在对字符数据输入的时候,由于缓冲区中有回车空格等数据,会导致输入数据比较诡异,为了解决这个问题,有以下方法:

(1) 清空缓冲区

在微软系统中,有一个名为fflush(stdin)的函数,可以用来清空缓冲区,如下例4。

#include

intmain()

{

chara ,b ;

printf("Input the value of a and b:");

while(scanf("%c%c",&a,&b)!=EOF)

{

printf("a=%c,b=%c\n",a,b);

fflush(stdin);

printf("Input the value of a and b:");

}

return0;

}

运行结果:

0818b9ca8b590ca3270a3433284dd417.png

(2)将缓冲区的数据读出来

有的编译系统并没有定义stdin的fflush操作,这个时候,可以把缓冲区中的数据读出来,有如下几种可行的方法:

1) getchar()

将例4中的fflush(stdin);语句换成

char c;

while((c=getchar())!='\n'&&c!=EOF);

运行效果和上面的相同。

2)gets()

char* gets(char* buffer)从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为null值,并由此来结束字符串。读入成功,返回与参数buffer相同的指针;读入过程中遇到EOF(End-of-File)或发生错误,返回NULL指针。所以在遇到返回值为NULL的情况,要用ferror或feof函数检查是发生错误还是遇到EOF。

要注意的是gets函数可以无限读取,不会判断上限,所以应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。如果溢出,多出来的字符将被写入到堆栈中,这就覆盖了堆栈原先的内容,破坏一个或多个不相关变量的值。

将例4中的fflush(stdin);语句换成

char c[10];

gets(c);

运行效果也和上面的相同。

#include

#include

#include

char*method1(void)

{

staticchara[4];

scanf ("%s\n", a);

returna;

}

intmain(void)

{

char*h = method1();

printf ("%s\n", h);

return0;

}

运行结果:

ab

cd

ab

Press any key to continue

可以发现,输如两次之后才会输出。这个现象比较诡异,原因如下:

White space (such as blanks, tabs, or newlines) in the format string match any amount of white space, including none, in the input.  Everything else matches only itself. Thus with scanf ("%s\n", a) it will scan for a string followed by optional white space. Since after the first newline more whitespace may follow, scanf is not done after the first newline and looks what's next. You will notice that you can enter any number of newlines (or tabs or spaces) and scanf will still wait for more. However, when you enter the second string, the sequence of whitespace is delimited and scanning stops.

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39920629/article/details/116988025

智能推荐

Linux 文件压缩与解压相关-程序员宅基地

文章浏览阅读85次。tar [-cxtzjvfpPN] 文件与目录 ....参数:-c :建立一个压缩文件的参数指令-x :解开一个压缩文件的参数指令-t :查看压缩文件里面的文件特别注意: c/x/t 同时只能存在一个,原因是我们不可能同时压缩与解压缩。-z :是否同时具有 gzip 的属性?亦即是否需要用 gzip 压缩-j :是否同时具有 bzip2 的属性?亦即是否需要用 bzi...

memcpy 函数详解-程序员宅基地

文章浏览阅读9.1k次。原型:extern void *memcpy(void *dest, void *src, unsigned int count);用法:#include 功能:由src所指内存区域复制count个字节到dest所指内存区域。说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。举例: // memcpy._memcpy

微型计算机电路基础第四版逻辑门,数字逻辑的电路基础——逻辑门.PDF-程序员宅基地

文章浏览阅读219次。数字逻辑的电路基础——逻辑门课程代码第三讲数字逻辑的电路基础——逻辑门佟冬Microprocessor R&D Centertongdong@/courses/digital/2010fall 1课程回顾 布尔代数 6个公设 10个定理 用于开关函数的化简 开关函数(3种表示方法) 直值表 布尔表达式(SOP, POS) 最小范..._微型计算机电路基础(第4版)教案

SimpleAdmin手摸手教学之:请求代理-程序员宅基地

文章浏览阅读56次。在之前使用其他admin的时候,经常会有人再部署的时候会遇到这么一个问题:明明在生产环境中配置了后端的api地址,但是通过nginx部署之后,请求的确是本地的地址。这是因为在项目中配置了代理,部署之后所有的请求都走了代理导致配置文件地址失效,关于vite代理说明,请自行百度,针对这种情况,本系统通过开关的方式让开发者自行选择是否走代理。

BZOJ 4245: [ONTAK2015]OR-XOR-程序员宅基地

文章浏览阅读81次。要求or的值最大,从高位到低位贪心,高位尽量为0,所以要求优先满足高位每段的xor和都相等转化为前缀和就是选出0的个数能否>=m#include<cstdio>using namespace std;int vis[1000005];long long a[1000005],Sum[1000005];int main(){ int n,m; s..._[ontak2015] or-xor

蜂群算法与多目标优化的结合:实践经验与效果-程序员宅基地

文章浏览阅读864次,点赞21次,收藏21次。1.背景介绍蜂群算法(Particle Swarm Optimization, PSO)是一种基于自然界蜂群行为的优化算法,由阿德利·迪亚斯(Adelia Diana)和伊瑟尔·阿迪亚德(Eckhardt Adia)于2001年提出。蜂群算法是一种简单、高效的全局优化算法,主要应用于解决连续优化问题。然而,随着现实世界中的优化问题变得越来越复杂,单目标优化算法已经无法满足需求。多目标优化问题是..._多蜂群优化算法

随便推点

遍历,toArray()_哪些数据结构可以使用toarray()-程序员宅基地

文章浏览阅读269次。任何数据结构,能够遍历,就能放到一个数组里,即toArray()。放在数组里,有利于操作,可以同时读取前面或后面的数据,而在其他数据结构里,则不是那么容易的,例如树_哪些数据结构可以使用toarray()

手机usb计算机连接不能选择,USB调试 是灰色按钮,无法点击,现在手机无法与电脑连接。...-程序员宅基地

文章浏览阅读9.6k次。USB调试 是灰色按钮,无法点击,现在手机无法与电脑连接。以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!USB调试 是灰色按钮,无法点击,现在手机无法与电脑连接。你好!首先你要先打开开发者选项(最上面)才可以再打开USB调试三星手机WLAN连接按钮是灰色,无法点击手机重启试试。如果依旧不能点击打开,就把手机恢复出厂设置..._usb计算机连接无法选择

我所理解的Android模块化(一)——模块化概念和路由_安卓模块那个是子模块和父模块-程序员宅基地

文章浏览阅读1.2w次,点赞13次,收藏84次。笔者在公司的项目中使用模块化的方式开发APP已经快一年的时间,其中经历过以模块化的方式来重构项目中一些相对来说业务比较独立的模块。遇到了一些问题,也积累了一些经验,所以想谈一谈我对Android模块化的理解,也希望能帮助到大家。_安卓模块那个是子模块和父模块

深度学习实战14(进阶版)-手写文字OCR识别,手写笔记也可以识别了_ocr.recognize_text-程序员宅基地

文章浏览阅读3.2k次,点赞2次,收藏20次。大家好,我是微学AI,今天给大家带来手写OCR识别的项目。手写的文稿在日常生活中较为常见,比如笔记、会议记录,合同签名、手写书信等,手写体的文字到处都有,所以针对手写体识别也是有较大的需求。_ocr.recognize_text

存储器的层次结构-程序员宅基地

文章浏览阅读1.5w次,点赞5次,收藏66次。文章目录存储器的层次结构1.存储器的多层结构2.多层结构的存储器系统3.程序的装入和链接(1) 程序的装入(2)程序的链接存储器的层次结构1.存储器的多层结构对于通用计算机而言,存储层次至少应具有三级:最高层为CPU寄存器,中间为主存,最底层是辅存。在较高档的计算机中,还可以根据具体的功能细分为寄存器、高速缓存、主存储器、磁盘缓存、固定磁盘、可移动存储介质等6层。如下图所示。2.多层结构..._存储器的层次结构

AJAX请求 状态pending_http请求 pending-程序员宅基地

文章浏览阅读4.3k次。一、pending 是什么意思?定义:信号产生和传递之间的时间间隔内,称此信号是未决的;简单的说就是:一个已经产生的信号,但是还没有传递给任何进程,此时该信号的状态就称为未决状态。二、HTTP Status pending 相关状态还包括哪些?1、待定状态;2、未决状态;3、等待状态;4、检验状态三、出现“pending”如何解决?通过上面讲了“pending 是什么意思?”你应该能明白一个大概的意思了吧,也有了一个大概的解决思路了吧。绝大多数情况都是因为..._http请求 pending

推荐文章

热门文章

相关标签