scanf()的说明和使用gets()的说明和使用scanf("%s")和gets()的区别关于~和EOF
scanf()的说明和使用scanf(完成函数为int scanf(const char *format, …))属于库函数
#include#include #include int main(){ int n=0; char c,str[10]; scanf("%d %c %s",&n,&c,&str); printf("%d %c %s",n,c,str); return 0; }
输入为: 23 A abcd(每次输入后都回车) 输出为: 23 A abcd 一切正常
但是如果我这样写:
#include#include #include int main(){ int n=0; char c,str[10]; scanf("%d",&n); scanf("%c",&c); scanf("%s",&str); // scanf("%d %c %s",&n,&c,&str); // printf("%d %c %s",n,c,str); printf("n=:%dn",n); printf("c=:%cn",c); printf("str=:%sn",str); return 0; }
还是原样,输入为: 23 A abcd(每次输入后都回车)
这个时候的输出为:23 A(程序在我输入A以后就结束了,并没有给我输入abcd的机会)
仔细观察输出你就会发现,c的值看似是null,但其实是我们输入的回车,这点可以用输出ASCII码来验证,修改c的输出
#include#include #include int main(){ int n=0; char c,str[10]; scanf("%d",&n); scanf("%c",&c); scanf("%s",&str); // scanf("%d %c %s",&n,&c,&str); // printf("%d %c %s",n,c,str); printf("n=:%dn",n); printf("c=:%dn",c); printf("str=:%sn",str); return 0; }
同样的输入,结果为:
PS:10为换行/新行的十进制ASCII码,也就是说scanf中的%c会吃回车,经测试%s并不会,在这里可以使用getchar()来抢先吃掉回车,代码为:
#include#include #include int main(){ int n=0; char c,str[10]; scanf("%d",&n); getchar();//新加了这个来吃掉输入结束后敲得回车 scanf("%c",&c); scanf("%s",&str); // scanf("%d %c %s",&n,&c,&str); // printf("%d %c %s",n,c,str); printf("n=:%dn",n); printf("c=:%dn",c); printf("str=:%sn",str); return 0; }
scanf还可以使用%f,%lf来分别读取单精度浮点数(float)和双精度浮点数(double),用法和%d相同。
scanf返回值问题:
scanf有三种返回值,分别是:
正整数:代表输入赋值成功,正整数为赋值成功变量的数量
零: 0表示输入异常,一般指输入错误的数据类型,要整数你偏给字符
-1: -1表示输入流结束,可以使用scanf()!= -1来判断输入是否结束,自己测试的时候可以用Ctrl+Z结束输入
#includegets()的说明和使用#include #include int main(){ int n1=0,n2=0,n3=0,n4=0,m=0,k=0,a,b; n1 = scanf("%d",&m); n2 = scanf("%d %d",&a,&b); n3 = scanf("%d",&k); printf("m=:%dn",m); printf("a=:%dn",a); printf("b=:%dn",b); printf("n1=:%dn",n1); printf("n2=:%dn",n2); printf("n3=:%dn",n3); printf("n4=:%dn",n4); return 0; }
char *gets(char *str)函数的功能是从输入缓冲区中读取一个字符串存储到变量 str 所指向的内存空间,str 可以是一个字符指针变量名,也可以是一个字符数组名
#includescanf("%s")和gets()的区别#include #include int main(){ char str1[10]; gets(str1); printf("str1=: %s",str1); return 0; }
先说结论:
scanf("%s")遇到空格会停,gets()遇到空格不停,会把空格读走,并且作为一个元素,放在字符数组中。
scanf("%s")不读取回车,输入结束时敲得那个回车scanf("%s")不要,也不会读走,而是留在缓冲区给下一个“有缘人”。gets()读取回车,并且以读取到回车作为结束标志,scanf("%s")结束的依据是输入流是否为空或者返回值是否等于变量数,即括号的内的变量是否都已经赋值完成。
#include#include #include int main(){ char str1[10],str2[10]; scanf("%s",&str1); scanf("%s",&str2); // gets(str1); //gets(str2); printf("str1=: %sn",str1); printf("str2=: %s",str2); return 0; }
啥也不输入直接狂按回车,没有任何反应。
gets()遇到空格不停,会把空格读走,并且作为一个元素,放在字符数组中。
#include#include #include int main(){ char str1[10],str2[10]; // scanf("%s",&str1); // scanf("%s",&str2); gets(str1); gets(str2); printf("str1=: %sn",str1); printf("str2=: %s",str2); return 0; }
gets()遇到回车会结束输入(这里啥都没输,直接敲了两个回车)
scanf()结束看返回值,即变量是否全部赋值完成
#include#include #include int main(){ char str1[10],str2[10]; scanf("%s %s",&str1,&str2); //scanf("%s",&str2); //gets(str1); //gets(str2); printf("str1=: %sn",str1); printf("str2=: %s",str2); return 0; }
这里第一个abcd被str1读走,但是str2还没有成功赋值,所以即使我狂敲回车,scanf依然不会放弃str2,知道我再次输入abcd,赋值给str2,输入结束
#关于~的作用
在Windows下,用户按下Ctrl+Z(会看到一个^Z字符),会停止输入流,scanf会返回-1。-1的补码为11111111 11111111 11111111 11111111 一共4个字节。~是C语言中的按位取反,
~(-1)结果为00000000 00000000 00000000 00000000刚好为整数0的补码。
因此当输入Ctrl+Z时,scanf会返回-1,while(~-1)==while(0),0为假,退出while循环。
#EOF
在C语言中,或更精确地说成C标准函数库中表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志,例如
#includeint main(void) { int n,i; int array[25]; while(scanf("%d",&n)!=EOF) { for (i=0; i ————————————————
~部分解释源自CSDN博主「saysine2020」的原创文章
原文链接:https://blog.csdn.net/zys_shan/article/details/104393211
EOF部分源自百度百科
原文链接:https://baike.baidu.com/item/EOF/1017800?fr=aladdin



