Обрезка завершающего \ 0 из fgets () в C - PullRequest
0 голосов
/ 13 сентября 2018

Я пишу простую программу оболочки на C, где программа принимает команды от пользователя в командной строке, маркирует входные данные в массив и затем использует функцию execvp () для выполнения пользовательских команд. Для чтения пользовательского ввода я использую функцию fgets ():

char command[MAX];
fgets(command, MAX, stdin);

Теперь вот где моя проблема (и я очень плохо знаком с программированием на C). Если пользователь вводит, например, ls -af и я проверяю длину набираемой строки, например

strlen(command)

результат - 7, хотя набрано всего 6 символов. Я понимаю, что это потому, что fgets () всегда добавляет \ 0 в конце строки. Это, однако, вызывает проблемы для моей программы позже. Я токенизирую ввод с помощью функции strtok () следующим образом:

char* token;
int i = 0;
char* args[10];
token = strtok(command, " ");
while(token != NULL)
  {   
      args[index] = token;
      token = strtok(NULL, " ");
      index ++ ;
   }
  args[index] = NULL;

После этого последний элемент в массиве args перед NULL (в данном случае -af) сохраняет тот трейлинг \ 0, который выдает fgets (). Это, в свою очередь, вызывает проблему для моего вызова execvp (), так как он не распознает последний элемент в массиве. Я предполагаю, что это читает это как -af \ 0, тогда как это должно быть просто -af. Есть ли способ обрезать последний \ 0, созданный функцией fgets (), или есть более простой способ прочитать ввод от пользователя? Заранее спасибо!

1 Ответ

0 голосов
/ 17 сентября 2018

Как указано в комментариях выше, вы, вероятно, видите новую строку, хранящуюся в строке.

Чтение страницы MAN (3) для fgets (выделено мной):

fgets () считывает из потока самое большее на один символ меньше размера и сохраняет их в буфере, указанном s. Чтение останавливается после EOF или новой строки. Если читается новая строка, она сохраняется в буфере. Завершающий нулевой байт ('\ 0') сохраняется после последнего символа в буфере.

Если вы хотите удалить символы новой строки, вы можете увидеть этот пост , в котором есть ответ, предлагающий использовать что-то вроде этого:

buffer[strcspn(buffer, "\n")] = 0;
...