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=:%d\n",n);
printf("c=:%c\n",c);
printf("str=:%s\n",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=:%d\n",n);
printf("c=:%d\n",c);
printf("str=:%s\n",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=:%d\n",n);
printf("c=:%d\n",c);
printf("str=:%s\n",str);
return 0;
}
scanf还可以使用%f,%lf来分别读取单精度浮点数(float)和双精度浮点数(double),用法和%d相同。
scanf返回值问题:
scanf有三种返回值,分别是:
正整数:代表输入赋值成功,正整数为赋值成功变量的数量
零: 0表示输入异常,一般指输入错误的数据类型,要整数你偏给字符
-1: -1表示输入流结束,可以使用scanf()!= -1来判断输入是否结束,自己测试的时候可以用Ctrl+Z结束输入
#include
#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=:%d\n",m);
printf("a=:%d\n",a);
printf("b=:%d\n",b);
printf("n1=:%d\n",n1);
printf("n2=:%d\n",n2);
printf("n3=:%d\n",n3);
printf("n4=:%d\n",n4);
return 0;
}
char *gets(char *str)函数的功能是从输入缓冲区中读取一个字符串存储到变量 str 所指向的内存空间,str 可以是一个字符指针变量名,也可以是一个字符数组名
#include
#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=: %s\n",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=: %s\n",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=: %s\n",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作为文件结束标志,例如
#include
int main(void)
{
int n,i;
int array[25];
while(scanf("%d",&n)!=EOF)
{
for (i=0; i<n; i++)
scanf("%d",&array[i]);
for (i=0; i<n; i++)
printf ("%d ",array[i]);
}
return 0;
}
————————————————
~部分解释源自CSDN博主「saysine2020」的原创文章
原文链接:https://blog.csdn.net/zys_shan/article/details/104393211
EOF部分源自百度百科
原文链接:https://baike.baidu.com/item/EOF/1017800?fr=aladdin