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

智能推荐

【数据结构】查找1——线性表的查找(顺序查找、折半查找、分块查找)_图顺序查找-程序员宅基地

文章浏览阅读2.8k次。【数据结构】查找1——线性表的查找(顺序查找、折半查找、分块查找)_图顺序查找

zip包解压时报malformed input off : 0, length : 1-程序员宅基地

文章浏览阅读843次。使用ZipArchiveInputStream而非ZipInputStream的原因主要有以下两点:支持更多的压缩格式:ZipArchiveInputStream是Apache Commons Compress库中提供的类,能够支持多种压缩格式,包括Zip、Gzip、Tar、Jar等。而ZipInputStream是Java标准库中的类,只能读取普通的Zip文件。因此,如果需要处理多种压缩格式的文件,使用ZipArchiveInputStream会更加方便。更多的选项和功能:ZipArchiveInp_malformed input off : 0, length : 1

switch case结合枚举值使用,借助枚举的值来做case分支判断_switch case 枚举-程序员宅基地

文章浏览阅读8.3k次,点赞9次,收藏22次。https://blog.csdn.net/m0_37754981/article/details/80022169参考资料_switch case 枚举

rpc简介及原理-程序员宅基地

文章浏览阅读5.1k次,点赞2次,收藏30次。1.RPC简介及原理介绍RPC技术内部原理是通过两种技术的组合来实现的:本地方法调用 和 网络通信技术。1.1 RPC简介在上述本地过程调用的例子中,我们是在一台计算机上执行了计算机上的程序,完成调用。随着计算机技术的发展和需求场景的变化,有时就需要从一台计算机上执行另外一台计算机上的程序的需求,因此后来又发展出来了RPC技术。特别是目前随着互联网技术的快速迭代和发展,用户和需求几乎都是以指数式的方式在高速增长,这个时候绝大多数情况下程序都是部署在多台机器上,就需要在调用其他物理机器上的程序的情况。_rpc

AI大视觉(十七) | PANet(路径聚合网络)-程序员宅基地

文章浏览阅读7k次,点赞6次,收藏70次。本文来自公众号“AI大道理​目标检测或者实例分割不仅要关心语义信息,还要关注图像的精确到像素点的浅层信息。所以需要对骨干网络中的网络层进行融合,使其同时具有深层的语义信息和浅层的纹理信息。PANet整体结构PANet(Path Aggregation Network)最大的贡献是提出了一个自顶向下和自底向上的双向融合骨干网络,同时在最底层和最高层之间添加了一条“short-cut”,用于缩短层之间的路径。PANet还提出了自适应特征池化和全连接融合两个模块。其中自适应特征_panet

OperationalError: (sqlite3.OperationalError) unable to open database file解决方案_sqlite3.operationalerror: unable to open database -程序员宅基地

文章浏览阅读1.3w次,点赞13次,收藏14次。本文主要介绍了OperationalError: (sqlite3.OperationalError) unable to open database file解决方案,希望能对使用langchain读取sqlite文件的同学们有所帮助。文章目录1. 问题描述2. 解决方案_sqlite3.operationalerror: unable to open database file

随便推点

PID控制详解-程序员宅基地

文章浏览阅读10w+次,点赞551次,收藏3.2k次。PID控制详解一、PID控制简介 PID( Proportional Integral Derivative)控制是最早发展起来的控制策略之一,由于其算法简单、鲁棒性好和可靠性高,被广泛应用于工业过程控制,尤其适用于可建立精确数学模型的确定性控制系统。 在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节,它实际上是一种算法。PID控制器问..._pid控制

搭建静态网站-程序员宅基地

文章浏览阅读329次。搭建Http静态服务器环境任务时间:15min ~ 30min搭建静态网站,首先需要部署环境。下面的步骤,将告诉大家如何在服务器上通过 Nginx 部署 HTTP 静态服务。00、安装 Nginx在 CentOS 上,可直接使用yum来安装 Nginxyum install nginx -y安装完成后,使用nginx命令启动 Nginx:n..._在一个目录下创建静态站点

HTML5网页设计 (一)_html5网页制作-程序员宅基地

文章浏览阅读7k次,点赞2次,收藏23次。初始HTML5记事本简单实现HTML5页面_html5网页制作

CentOS 固定IP配置_centos配置ip地址-程序员宅基地

文章浏览阅读6.8k次。1、打开 VMware Workstation,点击 “编辑” -> "虚拟网络编辑器"2、选择 “更改设置”(若界面内没有,则不用理会)3、选择 “VMnet8”,更改为192.168.88.0(按需填写)、为255.255.255.0,点击 “NAT设置”4、更改为192.168.88.2(按需填写),当前界面点击确定,“虚拟网络编辑器”界面再点击确定。_centos配置ip地址

MATLAB 调用 p文件,Matlab中使用.p文件的方法-程序员宅基地

文章浏览阅读2.9k次。首先,P文件为了保护知识产权设计的一种加密文件,是不能查看的。运行比较简单,和调用m文件方法一样。下面是一些解释。P文件是对应M文件的一种预解析版本(preparsedversion)。因为当你第一次执行M文件时,Matlab需要将其解析(parse)一次(第一次执行后的已解析内容会放入内存作第二次执行时使用,即第二次执行时无需再解析),这无形中增加了执行时间。所以我们就预先作解释,那么以后再使用..._matlab怎么调用p文件

[CSS] 内联元素内的文字居中显示(按钮、链接等)_a-button居中-程序员宅基地

文章浏览阅读2.1k次。最近在做一个移动端的响应式页面,对自定义样式要求较高,很多地方需要细微的调整,比如按钮、链接等内联元素,不能只是让它看起来居中,而要做到“响应式”居中……水平居中很简单,但是垂直居中的问题困扰了我很久,直到我研究过bootstrap的_variables.scss文档后,才仔细地了解到一些组件的构造。如果修改了inline/inline-block元素的默认样式后,里面的文字不居中了,试试这个方法,只需要5步~_a-button居中

推荐文章

热门文章

相关标签