C 整数安全输入

标签 c integer scanf gets

如何使用 scanfgets 获得整数(尤其是正数)的安全输入?我尝试了几种解决方案,每种解决方案都有一些问题。

<强>1。使用 getchar() 删除字符串输入

int safeInput() {
    int input;
    scanf("%d", &input);
    while(getchar() != '\n');
    return input;
}

该方法有效地处理字符串输入,但是,如果输入诸如3a之类的字符串,则input的值将变为3,即不是真正的异常句柄。

<强>2。以字符串形式检索输入,然后转换为整数值。

int safeInput() {
    char[200] input, safe_input;
    gets(input);
    // I know about the security issue about gets - but it's not the point.

    int i = 0;
    while (1) {
        if (input[i] >= 48 && input[i] <= 57) safe_input[i] = input[i];
        else break;
        i++;
    }

    return atoi(safe_input);
}

此方法存在一个问题,即如果输入的字符串长度比分配给 input 的长度长,则无法处理。

<强>3。如果使用指针定义字符串会怎样?

我关心的是通过指针定义input,例如char *input;。但是,一旦我执行 gets(input)(或 scanf("%s", input)),它就会引发运行时错误。


那么使用 scanfgets 从控制台窗口检索整数值的正确方法是什么?

最佳答案

答案取决于您所说的安全到底是什么意思。安全。如果您想捕获任何可能的输入错误,唯一的选择是使用 strtol() 系列的函数,它甚至允许进行范围检查。在我的beginners' guide away from scanf() ,我正在描述它的用途。

这是适合您在此处尝试的代码,并带有注释:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>

// return success as boolean (0, 1), on success write result through *number:
int safeInput(int *number)
{
    long a;
    char buf[1024]; // use 1KiB just to be sure

    if (!fgets(buf, 1024, stdin))
    {
        // reading input failed:
        return 0;
    }

    // have some input, convert it to integer:
    char *endptr;

    errno = 0; // reset error number
    a = strtol(buf, &endptr, 10);
    if (errno == ERANGE)
    {
        // out of range for a long
        return 0;
    }
    if (endptr == buf)
    {
        // no character was read
        return 0;
    }
    if (*endptr && *endptr != '\n')
    {
        // *endptr is neither end of string nor newline,
        // so we didn't convert the *whole* input
        return 0;
    }
    if (a > INT_MAX || a < INT_MIN)
    {
        // result will not fit in an int
        return 0;
    }

    // write result through the pointer passed
    *number = (int) a;
    return 1;
}

关于C 整数安全输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50096953/

相关文章:

connect() 或accept() 的客户端服务器问题

c++ - 库中所有符号的显式名称修改(也称为名称修饰)

r - 什么是 R 中的整数溢出,它是如何发生的?

c - 如何读取字符串直到两个连续的空格?

c++ - 在编译系统中,链接器(ld)如何知道将myprogram.o链接到谁?

c - 查找不能表示为 IEEE-754 32 位 float 的最小整数

database - 整数压缩法

java - 在Android上将字符串转换为整数

C:如何使用while循环计算多位整数的位数?

c - 循环重复scanf和printf