C - программа завершает работу, когда ввод превышает допустимое значение fgets

У меня есть следующая программа, написанная на C:

Основная проблема с этой программой заключается в том, что если ввод превышает 80 символов при использовании функции fgets(), программа просто немедленно завершает работу. Другой код выполняется, однако он не ждет, пока пользователь нажмет Enter. Он просто игнорирует getchar в конце.

Как я могу решить эту проблему, пожалуйста?


person Matthew    schedule 23.11.2012    source источник
comment
Возможно, вы также захотите переосмыслить это самоудаление новой строки (кроме вашего заданного вопроса, на который легко ответить ниже). Если ввод длиннее 80 символов, в буфере нет новой строки, и вы официально перезаписываете пользовательские данные. Не критическая ошибка, а просто логическая, которая в данном случае приводит к потере содержимого пароля.   -  person WhozCraig    schedule 23.11.2012


Ответы (2)


Если пользовательский ввод длиннее 79 символов, которые fgets может прочитать из stdin (он может прочитать не более чем на один символ меньше, чем указано в его параметре размера, поскольку он завершает буфер 0), оставшийся ввод остается во входном буфере, следовательно getchar() в конце сразу преуспевает.

Чтобы избежать этого, вам нужно очистить буфер ввода, если ввод был слишком длинным.

Проблема в том, что если ввод был достаточно коротким, вы не знаете, очищать буфер или нет. Так что проверьте, действительно ли вы получили новую строку, прочитанную fgets,

int len = strlen(password);
if (password[len-1] == '\n') {
    // got a newline, all input read, overwrite newline
    password[len-1] = 0;
} else {
    // no newline, input too long, clear buffer
    int ch;
    while ((ch = getchar()) != EOF && ch != '\n');
    if (ch == EOF) {
        // input error, stdin closed or corrupted, what now?
    }
}
person Daniel Fischer    schedule 23.11.2012

Проверьте, был ли fgets() прочитан символ новой строки, и если не пропустить ввод, пока не встретится символ новой строки:

if (0 == strrchr(password, '\n'))
{
    /* Skip until new-line. */
    int c;
    while (EOF != (c = getchar()) && '\n' != c);
}

в противном случае вызов getchar() будет читать то, что не сделал fgets().

person hmjd    schedule 23.11.2012