Проблемы ввода / вывода

#define MAX_COMMAND_LEN 32

char command[MAX_COMMAND_LEN];
while (1) {
    if (fgets(command, MAX_COMMAND_LEN, stdin) == NULL) {
        perror("Error: standard function fgets has failed\n");
        break;
    }

    if (command[strlen(command) -1] != '\n') {
        printf("Error: command length must be less than or equal to 30 characters\n");
        continue;
    }
    else {
         printf("Error: command not found\n");
    }

}
quit();

У меня есть пара проблем, с которыми я не могу справиться:

  1. Когда я нажимаю Enter, он останавливает цикл и не печатает command not found сообщение.
  2. Когда я ввожу команду размером более 30 символов, она печатает как command not found и command length must be less than or equal to 30 characters Сообщения.
  3. Когда я ввожу команду размера 64, она печатает дважды сообщение длиной 30.

Я полагаю, что он делит ввод на сегменты длиной 30 и вводит каждый из них, как мне преодолеть это? Я пытался смыть stdin, это не работает. Я хочу избавиться от остальной части ввода. Как мне преодолеть все эти проблемы?

4 ответа

Решение

Для вашей второй проблемы это потому, что fgets выбирает 31 (MAX_COMMAND_LENминус место для окончания '\0' персонаж) первые символы, вы заметите, что это не перевод строки и в следующий раз в цикле fgets получает оставшиеся символы

Когда я ввожу команду размером более 30 символов, она печатает как "команда не найдена", так и "длина команды должна быть меньше или равна 30 символам".

fgets читает максимум MAX_COMMAND_LEN - 1 персонажи, как это оставляет место для '\0',
Вот почему для любого сообщения длиной более 30 символов, первые 31 символов, которые fgets читает не содержат '\n' и так отображается сообщение длиной 30.
Поскольку вторая часть команды имеет '\n' в конце концов, command not found также печатается.

Когда я ввожу команду размера 64, она печатает дважды сообщение длиной 30.

fgets вызывается 3 раза для этой команды. Читается первый фрагмент длиной 31, затем читается второй фрагмент длиной 31, а затем остальные символы. Оба куска длиной 31 не содержат '\n' символ и, следовательно, сообщение длиной 30 отображается дважды.

Вы, возможно, неправильно поняли, как fgets на самом деле работает:

char * fgets ( char * str, int num, FILE * stream ); Считывает символы из потока и сохраняет их в виде строки C в строке str до тех пор, пока не будет прочитано (num-1) символов или не будет достигнута новая строка или конец файла, в зависимости от того, что произойдет раньше. Символ новой строки заставляет fgets перестать читать, но он считается допустимым символом и поэтому включен в строку, скопированную в str. Нулевой символ автоматически добавляется в str после прочитанных символов, чтобы обозначить конец строки C.

Так,

  1. когда вы нажимаете "Enter" - он вводит новую строку, и это не исключительный случай в вашем коде.
  2. когда вы вводите строку длиной более 30 символов fget читает это несколько раз.
  3. то же самое с 60 символами - символ новой строки НЕ является последним символом строки, поэтому вы получаете ошибку дважды.

На вопрос (я), извините, я не знаю почему, потому что моя программа выдает правильный вывод.

Для вопроса (ii) вы даете второму аргументу fgets значение 32, функция будет читать не более 32 символов, включая '\n' и '\0'; то, что осталось, все еще находится в буфере stdin, и когда ваша программа продолжит работу после печати ошибки, fgets будет считывать оставшиеся символы в буфере stdin, пока не будет прочитано '\n'.

Если вы хотите сбросить стандартный ввод, вам нужно fpurge(stdin) функция для очистки буфера стандартного ввода.

Другие вопросы по тегам