Проблемы ввода / вывода
#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();
У меня есть пара проблем, с которыми я не могу справиться:
- Когда я нажимаю Enter, он останавливает цикл и не печатает
command not found
сообщение. - Когда я ввожу команду размером более 30 символов, она печатает как
command not found
иcommand length must be less than or equal to 30 characters
Сообщения. - Когда я ввожу команду размера 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.
Так,
- когда вы нажимаете "Enter" - он вводит новую строку, и это не исключительный случай в вашем коде.
- когда вы вводите строку длиной более 30 символов
fget
читает это несколько раз. - то же самое с 60 символами - символ новой строки НЕ является последним символом строки, поэтому вы получаете ошибку дважды.
На вопрос (я), извините, я не знаю почему, потому что моя программа выдает правильный вывод.
Для вопроса (ii) вы даете второму аргументу fgets значение 32, функция будет читать не более 32 символов, включая '\n' и '\0'; то, что осталось, все еще находится в буфере stdin, и когда ваша программа продолжит работу после печати ошибки, fgets будет считывать оставшиеся символы в буфере stdin, пока не будет прочитано '\n'.
Если вы хотите сбросить стандартный ввод, вам нужно fpurge(stdin)
функция для очистки буфера стандартного ввода.