今天遇到一道题要求输入scanf("%c %c %c\n",&a,&b,&c),结果不停地出现问题,经过许久尝试,终于发现是\n出现了问题,scanf遇到\n看到另有玄机。这种情况下会要去多输入一行,才有用,但是实际读入的却还是第一次输入的那一行。看下面的例子:
#include<stdio.h>
int main(void)
{
int n;
scanf("%d\n",&n);
printf("%d",n);
return 0;
}
那个简单的代码,必须如下输入才有用,
从中可以看见我多输入了一行,方才成功,但是最后输出的结果却是第一次输入的数字‘5’,这就十分奇怪了。于是上网进行了查阅。
看到两个说法,感觉这两种说法合起来应该能大致有所理解。
链接1:https://blog.csdn.net/weiweicsdn1/article/details/52185453
链接2:https://zhidao.baidu.com/question/289196414.html
我个人理解是这样的:scanf("%d\n",&n);这样一条语句,输入一个数字加回车,5\n全部被读入到了scanf中去了,然后5被赋给了n,但是这样在缓冲区内此时却没有空白符,因此无法结束,然后根据scanf的规定,必须要有一个空白符才能够结束输入,因此还会要求继续输入,而\n后面需要遇到一个非空白符才能继续读入,否则会一直提示输入,因此再输入一个非空白符,一个空白符即可成功完成scanf的停止。
此外顺便记录下vs的scanf_s函数,_s函数一般是为了安全而设计的,但是功能实际上是一样的,
Tree BuildTree( struct TreeNode T[] )
{
int Root = Null;
int check[10];
int i,N;
char cr, cl;
scanf_s("%d\n", &N);
//printf("%d\n",N);
if (N) {
for (i=0; i<N; i++) check[i] = 0;
for (i=0; i<N; i++) {
scanf_s("%c %c %c\n", &(T[i].Element),1, &cl,1, &cr,1);
//printf("line42 still ok");
//deal with the cl
if (cl != '-') {
//printf("line45 still ok");
T[i].Left = cl-'0';
printf("%d\n",T[i].Left);
check[T[i].Left] = 1;
}
else T[i].Left = Null;
/*deal with the cr*/
if (cr != '-') {
T[i].Right = cr-'0';
//printf("%d\n",T[i].Right);
check[T[i].Right] = 1;
}
else T[i].Right = Null;
}
for (i=0; i<N; i++)
if (!check[i]) break;
Root = i;
}
return Root;
}
以上是在vs中成功执行的代码,之前 scanf_s("%c %c %c\n", &(T[i].Element),&cl,&cr);报出了很多警告,好像是越界问题,然后在后面加上输入的字符的大小就成功执行了。