验证用户输入时如何处理缓冲区错误

时间:2018-02-02 23:04:39

标签: c validation scanf user-input

我需要将用户输入作为整数读入,以将其传递给我的其他函数。如果我使用我的验证(下面的代码),它会在4次错误输入后崩溃。我不完全确定这是否是一个缓冲区错误。但我也没有找到一种正确的方法来验证我的输入并处理错误。我没有故意使用scanf(%d),因为我想避开CLion在使用它时给我的警告。我希望这里有人可以向我解释为什么我的代码在4个错误的输入之后崩溃以及如何修复它,或者向我展示另一种方式。

char *userInput = malloc(100);
long amountOfPlayers;
//Todo: More Validation needed, bufferoverflow
for (int i = 0; i < sizeof(userInput) / sizeof(*userInput); i++) {
    char *end;
    printf("Please enter the amount of players: ");
    scanf("%s", userInput);
    amountOfPlayers = strtol(userInput, &end, 10);
    if (end == userInput) {
        printf("wasn't a number\n");
    }
    else if (end[0] != '\0') {
        printf("trailing characters after number %ld: %s\n", amountOfPlayers, end);
    }
    else
        return init_playerList(amountOfPlayers);
}

2 个答案:

答案 0 :(得分:1)

userInput是指针,而不是数组,因此sizeof(userInput)返回指针的大小,通常为4个字节。 sizeof(*userInput)sizeof(char),即1。所以sizeof(userInput) / sizeof(*userInput)是4,这意味着你的for循环只执行4次。见How to find the 'sizeof' (a pointer pointing to an array)?

不需要for循环,只需使用while (true)即可。你没有做任何迭代userInput元素的事情,它只是缓冲区。

也没有理由用malloc()分配它,您只需声明:

char userInput[100];

您有内存泄漏,因为在从函数返回之前从未free(userInput)。但如果你将它声明为一个数组,则没有必要。

为防止缓冲区溢出,您应该使用:

scanf("%100s", userInput);

答案 1 :(得分:0)

sizeof(userInput) / sizeof(*userInput)不会返回元素数,因为userInput是指针而不是数组。这仅适用于纯数组。如果指针总是返回相同的值:指针的大小除以对象的大小。

int size = 100;
char *userInput = malloc(size);
if(userInput == NULL)
{
    // error handling
}

for (int i = 0; i < n; i++) {
    ....
}

是正确的。