如何防止用户输入超过最大限制的数据?

Laz*_*zer 4 c stdin flush fgets

此代码向用户询问数据,然后询问数字:

$ cat read.c
#include<stdio.h>
#include<stdlib.h>
#define MAX 10

int main() {
    char* c = (char*) malloc(MAX * sizeof(char));
    int num;

    printf("Enter data (max: %d chars):\n", MAX);
    fgets(c, MAX, stdin);
    // how do I discard all that is there on STDIN here?

    printf("Enter num:\n");
    scanf("%d", &num);

    printf("data: %s", c);
    printf("num: %d\n", num);
}
$
Run Code Online (Sandbox Code Playgroud)

问题是,除了说明最大字符数的指令之外,没有任何东西可以阻止用户输入更多字符,随后将其读入num垃圾:

$ ./read
Enter data (max 10 chars):
lazer
Enter num:
5
data: lazer
num: 5
$ ./read
Enter data (max 10 chars):
lazerprofile
Enter num:
data: lazerprofnum: 134514043
$ 
Run Code Online (Sandbox Code Playgroud)

有没有办法丢弃通话STDIN后的所有信息fgets

Fré*_*idi 5

据我所知,唯一的便携式解决方案是自己耗尽缓冲:

while (getchar() != EOF);
Run Code Online (Sandbox Code Playgroud)

请注意,fflush(stdin);不是问题的答案.

编辑:如果你只想在下一个换行符之前丢弃字符,你可以这样做:

int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
Run Code Online (Sandbox Code Playgroud)


sps*_*ley 5

scanf()函数对于用户输入来说很糟糕,除非你以某种方式知道你的输入数据是正确的(不要那么信任!),否则它对于文件输入来说并不是那么好.另外,你应该总是检查fgets()的返回值因为NULL表示EOF或其他一些例外.请记住,除非首先达到最大值,否则在fgets()数据末尾会得到用户的换行符.作为第一遍,我可能会这样做:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10

void eat_extra(void) {
    int ch;

    // Eat characters until we get the newline
    while ((ch = getchar()) != '\n') {
        if (ch < 0)
            exit(EXIT_FAILURE); // EOF!
    }
}

int main() {
    char c[MAX+1]; // The +1 is for the null terminator
    char n[16]; // Arbitrary maximum number length is 15 plus null terminator
    int num;

    printf("Enter data (max: %d chars):\n", MAX);
    if (fgets(c, MAX, stdin)) { // Only proceed if we actually got input
        // Did we get the newline?
        if (NULL == strchr(c, '\n'))
            eat_extra(); // You could just exit with "Too much data!" here too

        printf("Enter num:\n");
        if (fgets(n, sizeof(n) - 1, stdin)) {
            num = atoi(n); // You could also use sscanf() here
            printf("data: %s", c);
            printf("num: %d\n", num);
        }
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)