#c #arrays #pointers
#c #массивы #указатели
Вопрос:
Я пишу простой интерпретатор командной строки. Мой код считывает строку с помощью scanf и анализирует ее с помощью функции getArgs(), показанной ниже, а затем использует этот массив в качестве аргумента execvp для выполнения команды, такой как ls. Это работает, если я вызываю только ‘ls’, но когда я вызываю ‘ls -la’, это дает тот же результат, что и ‘ls’.
void getArgs(char* command, char* args[]){
int i = 0;
char* p = strtok(command, " ");
args[i] = p;
while(p != NULL){
i ;
p = strtok(NULL, " ");
args[i] = p;
}
}
Вот моя основная функция, которая включает инициализацию заданных аргументов:
int main(){
char *args[1024];
char example[30];
char exit[5] = {'q', 'u', 'i', 't', ''};
int f1;
int status;
size_t n = sizeof(args)/sizeof(args[0]);
while(strncmp(example, exit, 30) !=0){
printf(">>>");
scanf("%s", example);
getArgs(example, args);
int x = strncmp(args[0], exit, 30);
if (x != 0){
f1 = fork();
if (f1 != 0){
/* wait for child process to terminate */
waitpid(f1, amp;status, 0);
}
else{myExec(args);}}
else{
return 0;}}
return 0;
}
Я предполагаю, что проблема заключается в том, что мой массив аргументов, args, не завершается нулем, и поэтому, когда я пытаюсь использовать его в myExec ():
void myExec(char* args[]){
execvp(args[0], args);
}
это не работает. Итак, мой вопрос в том, могу ли я присвоить элементу после последней непустой части моего массива значение null, чтобы попытаться заставить это работать? Если да, то как я могу это сделать? Есть ли лучший способ решить эту проблему?
Комментарии:
1. Я добавил остальную часть кода, также args[i] = strdup(p); выдает ‘Ошибка сегментации: 11’.
2. char exit[] = «выйти»;
Ответ №1:
-la
Игнорируется, потому что scanf("%s", example);
остановится на первом пробеле. Я предлагаю
scanf(" )[^n]", example);
Который будет
- Игнорируйте пробелы, оставшиеся в буфере от предыдущей команды.
- Ограничьте ввод строки от переполнения.
- Разрешить разделители пробелов в команде.
Также обратите внимание, что при первом выполнении while(strncmp(example, exit, 30) !=0)
the example
является неинициализированной переменной, поэтому это должно быть
char example[30] = "";
Ответ №2:
%s
Директива останавливает сканирование при первом пробельном символе, поэтому она не будет должным образом перехватывать любые команды с пробелами (например, ls -la
). Вы должны использовать fgets
для получения пользовательского ввода, если хотите сохранить какие-либо пробелы:
if ( fgets( example, sizeof example, stdin ) )
{
getArgs( example, args);
...
}
fgets
будет считано до sizeof example - 1
символов в example
(включая новую строку!) и 0-завершит строку. Возможно, вы захотите учесть этот перевод строки при вашем strtok
вызове.