使用scanf()进行验证以防止字符串

时间:2013-11-18 03:10:32

标签: c

我这里有一个代码,可以查看用户输入是字符串还是整数,范围是1-49。如果我输入“asdas”则表示无效,如果我输入“1-49”中的整数,则表示有效。我对这段代码的问题是,如果我输入“2 asda” 它会计算它有效,并且同时无效,如果我输入“2 2”它也会认为是有效的。刚发现它也接受“2d”作为有效输入。

for (i = 0; i < 6; i++)
        {

            printf("\nPlease enter the %d winning ticket numbers!: ", i+1);
            if (scanf("%d", (&winningNumbers[i])) == 0 || (winningNumbers[i] <= 0) || (winningNumbers[i] >= 50))
            {
                    inputFlush();
                    printf("\nInvalid Input. Please re-enter.\n") ;
                    i = i - 1;
            }
       }

        for (i = 0; i < 6; i++)
        {
            printf("%d, ", winningNumbers[i]);
        }

3 个答案:

答案 0 :(得分:2)

将整行读入一个字符串(fgets,在代码段中的第2行)。使用sscanf从字符串中读取数据:读取整数一个字符,读取空格。检查sscanf是否返回不同于1的内容。如果是,那么你要么在开头有字符串(它返回0因为它无法读取整数)或者你在末尾有额外的空格字符(就是它)也匹配%c格式说明符)。需要空格才能跳过空格直到行尾(包括存储的\n)。

printf("\nPlease enter the %d winning ticket numbers!: ", i+1);
fgets(buffer, size, stdin);
if (sscanf(buffer, "%d %c", &winningNumbers[i], &c) != 1 || (winningNumbers[i] <= 0) || winningNumbers[i] >= 50))
{
    // inputFlush(); not needed now that you read the entire line
    printf("\nInvalid Input. Please re-enter.\n") ;
    i = i - 1;
}

答案 1 :(得分:0)

看看这个例子。

#define MAX_LINE_SIZE 500

int main(int argc, char** argv)
{

    char line[MAX_LINE_SIZE];
    unsigned int num;
    char *ptr;

    while (fgets(line, MAX_LINE_SIZE, stdin) != NULL){
        num = strtol(line, &ptr, 10);
        if (line[0] != '\n' && (*ptr == '\n' || *ptr == '\0')) {
            printf("Your num: %u\n", num); // check num if you need
        } else {
            printf("Error\n");
        }
    }

    return 0;
}

输出:

12
Your num: 12
45
Your num: 45
34 2 
Error
ads
Error

这里fgets函数从stdin读取数据。 strtol解析读取字符串并将解析后的数字后的字符地址分配给ptr指针。假设用户只需要输入一个数字(之后没有任何字符),我们必须检查*ptr是新行还是行尾。

line[0] != '\n'可以防止空字符串。

答案 2 :(得分:-1)

使用peek检查下一个字符,详细为here。你可以用这种方式判断它是否好。

Another SO question这几乎是一样的。