2016-05-17 3 views
1
fgets(command, BUFFSIZE, stdin); 
command[strlen(command)-1] = '\0'; 

char *p = strtok(command, " "); 
char *command_tok[BUFFSIZE]; 
int i = 0; 
while (p) { 
    command_tok[i++] = p; 
    p = strtok(NULL, " "); 
} 


char *commands[] = {*command_tok, NULL}; 
execvp(command_tok[0], commands); 

Я пытаюсь получить пользовательский ввод, tokenize его и сохранить команду и аргументы в массиве, чтобы передать его execvp(). Однако аргументы никогда не читаются. Если вход «ls -l», он всегда выполняется как «ls».Tokenize пользовательский ввод для execvp() в c

ответ

3

Эта линия:

// makes a two element array 
char *commands[] = {*command_tok, NULL}; 

неправильно.

Он создает новый массив, состоящий из двух элементов, первым из которых является command_tok [0]. Вместо того, что вы хотите

command_tok[i] = NULL 
    execvp(command_tok[0], command_tok); 

Также

command[strlen(command)-1] = '\0' 

бессмысленна: StrLen находит длину путем поиска нулевого байта, который затем установить снова нуль.

Вот моя версия:

#include <string.h> 
#include <unistd.h> 

#include <cstdio> 
static const int BUFFSIZE=200; 

int main(int argc, char* argv[]) { 
    char command[BUFFSIZE] = { 0 }; 
    fgets(command, BUFFSIZE, stdin); 
    // remove trailing new line if present 
    commmand[strcspn(command, "\n")] = 0; 

    char *p = strtok(command, " "); 
    char *command_tok[BUFFSIZE]; 
    int i = 0; 
    while (p) { 
    command_tok[i++] = p; 
    p = strtok(NULL, " "); 
    } 

    command_tok[i] = NULL; 
    execvp(command_tok[0], command_tok); 
} 

Один вкладыша для удаления заднего новой линии происходил из Removing trailing newline character from fgets() input

0

Вы предоставляете commands массив, состоящий ровно из двух элементов: элемент (первый) command_tok указывает на и NULL. Как компилятор должен знать, что вы имеете в виду все элементы массива command_tok, и как он должен определять его размер?

1

После -l не имеет места, поэтому, ваш вариант принимает " -l \ n 'в качестве аргумента. Поэтому вы должны использовать '\ n' также в разделителе в функции strtok.

Этот код будет работать так, как вы ожидали.

fgets(command, BUFFSIZE, stdin); 
command[strlen(command)-1] = '\0'; 

char *p = strtok(command, " \n"); 
char *command_tok[BUFFSIZE]; 
int i = 0; 
while (p) { 
    command_tok[i++] = p; 
    p = strtok(NULL, " \n"); 
} 
command_tok[i] = NULL; 

execvp(command_tok[0], command_tok); 

При использовании fgets для чтения ввода, если это не EOF, то есть \ п в прошлом. Таким образом, используя это, вы можете выбрать аргумент.