首页 > 解决方案 > 使用缓冲区而不是直接对整数使用 scanf 函数的原因

问题描述

所以我有这段代码,它是为读取用户输入而编写的,它应该在数字 1-9 之间。在代码中声明了 int “选择”。但不是使用scanf("%d", choice);程序员直接扫描用户输入,而是使用 char 缓冲区并扫描缓冲区,然后使用 atoi 函数将 char 输入转换为整数。我很困惑为什么要这样做,而不是直接用简单的方法来做。我的假设是程序员已经这样做了,因此如果用户输入字符而不是数字,则代码不会出现故障。但如果是这种情况,那么 atoi 将如何将字母转换为整数?这是代码:

int readMenuChoice() {
    while (1) {
        char buffer[50];
        size_t buffLen =  10;
        int choice;
        showMenu(); //another function that displays all options from 1 to 9
        printf("Choose a menu option: ");
        scanf("%[^\n]", buffer);
        getchar();
        choice = atoi(buffer);
        if (choice > 0 && choice < 9) {
            return choice;
        }
        printf("Invalid input\n\n");
    }
}

标签: cscanfatoi

解决方案


我们只能从编码器那里猜测意图。

但一个很可能的原因是确保每个输入之间的输入流为空。我个人也做类似的事情。但我会这样做:

while (1) {
    char buffer[50];
    int choice;

    showMenu(); 
    printf("Choose a menu option: ");

    if(!fgets(buffer, sizeof buffer, stdin)) {
        /* Handle error */
    }

    if(sscanf(buffer, "%d", &choice) != 1) {
        /* Handle error */
    }

    if (choice > 0 && choice < 9) {
        return choice;
    }

    printf("Invalid input\n\n");
}

atoi是一个不安全的功能。如果参数无法解析为数字,则会调用未定义的行为。并且由于x = atoi(s)完全等同于sscanf(s, "%d", &x),所以没有理由使用 unsafe 函数。sscanf返回成功分配的数量,因此可以进行错误检查。


推荐阅读