C语言常见问题–scanf函数的输入问题
在前几天写推箱子的游戏的时候遇到了这个问题.在这里我把这个问题还原出来…并解决…
编译环境 :mac电脑、GCC编译器、VSCode代码编辑器.
第一段代码A
#include <stdio.h>
int main(int argc, char *argv[]) {
int num = 0;
scanf("%d", &num);
printf("src 0X%x, num = %d", num, num);
return 0;
}
运行结果:
bao:day1007 bao$ gcc -o test3 test3.c
bao:day1007 bao$ ./test3
5
src 0X5, num = 5bao:day1007 bao$
第二段代码B
#include <stdio.h>
int main(int argc, char *argv[]) {
int num = 0;
scanf("%d", &num);
printf("src 0X%x, num = %d", num, num);
// getchar();
putchar(getchar());
return 0;
}
运行结果:
bao:day1007 bao$ ./test3
5
src 0X5, num = 5
bao:day1007 bao$
知识点1
1、在代码A和代码B中,我都输入了 ‘5’ ‘回车’,但是运行结果却不一样.
原因:在键盘输入完之后(‘5’ 回车),输入的内容都保存在了标准输入的缓冲区.
scanf函数只是读取了5, 回车还留在标准输入的缓冲区.
2、代码B的回车被getchar( )读了出来.
如果你输入3s14a会是怎么样?
bao:day1007 bao$ gcc -o test3 test3.c
bao:day1007 bao$ ./test3
3s14a
src 0X3, num = 3bao:day1007 bao$
如果你输入423s14a会是怎么样?
bao$ ./test3
423s14a
src 0X1a7, num = 423bao:day1007 bao$
问题:1、为什么scanf函数只读取了423?
知识点2 (参考 man scanf的描述)
Matches an optionally signed decimal integer;
匹配可选带符号的十进制整数;
也就是说
1、只匹配十进制整数;(如果在输入的前面加几个空格等其他字符,返回就是null)
2、匹配到时候从非write space(回车、tab、空格)的第一个十进制整数开始,直到到不是十进制整数结束;
知识点3(参考 man scanf的描述)
scanf函数是从 标准输入 去读取内容.
print是想向 标准输出 去输出内容;
Linux一切皆文件.
代码C
#include <stdio.h>
int main(int argc, char *argv[]) {
char num = 0;
while (1) {
scanf("%c", &num);
printf("src 0X%x, num = %c---------", num, num);
}
return 0;
}
运行结果
bao:day1007 bao$ gcc -o test4 test4.c
bao:day1007 bao$ ./test4
2
src 0X32, num = 2---------src 0Xa, num =
---------3
src 0X33, num = 3---------src 0Xa, num =
我只输入一个 ‘2’‘回车’,然后就输出这样
根据上面的知识点,我们可以知道是因为缓冲去里面的回车导致的这个问题.
但是同样的输入,如果你的代码是这样的话就没有这个问题了
#include <stdio.h>
int main(int argc, char *argv[]) {
int num = 0;
while (1) {
scanf("%d", &num);
printf("src 0X%x, num = %d---------", num, num);
}
return 0;
}
bao:day1007 bao$ gcc -o test4 test4.c
bao:day1007 bao$ ./test4
2
src 0X2, num = 2---------3
src 0X3, num = 3---------4
src 0X4, num = 4---------
知识点4(参考 man page的描述)
1、%c -----会从缓冲区的第一个字符开始读取;
2、%s 、 %d--------都会“省略”前面的write space字符(空格、回车、tab建).然后在读取
那么我们怎么去处理%c多次输入的问题呢?
处理
第一种
在scanf(" %c", &num);
的%c前面加一个空格.
第二种
使用getchar函数“吃”那个回车字符.
scanf("%c", &num);
getchar();
printf("src 0X%x, num = %c---------", num, num);
第三种《没成功》
听说有个更新缓冲区的函数,
scanf("%c", &num);
fflush(stdin);
printf("src 0X%x, num = %c---------", num, num);
第四种
scanf("%c%*c", &num);
通过%*c吃掉一个字符,
也可以是%*s,吃掉一个字符串.
对于scanf有这些就可以够用了.,但是如果向深入了解关于标准输入,标准输出,和缓冲区,键盘,显示屏之间是怎么完成输入的…