C语言常见问题--scanf函数

本文探讨了C语言中scanf函数遇到的输入问题,包括只读取部分输入的原因,以及处理输入中回车符残留的多种方法。通过分析man scanf的描述,解释了scanf如何匹配十进制整数,并提供了代码示例展示不同输入情况下的行为。解决方案包括在%c前加空格、使用getchar()函数或利用%*c来处理回车字符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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有这些就可以够用了.,但是如果向深入了解关于标准输入,标准输出,和缓冲区,键盘,显示屏之间是怎么完成输入的…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值