Проблемы с передачей в char [] [] в execvp - PullRequest
1 голос
/ 04 мая 2019

Я пытаюсь перебрать некоторые входные данные (которые являются командами и аргументами), разделить входные данные на отдельные строки, а затем передать эти входные данные в execvp().

У меня проблема, поскольку execvp() хочет (char*, char*[]) в качестве аргументов. Я вхожу в (char*, char[][]), что я думал, было то же самое, но это не нравится.

Я бы использовал char*[], но я не знаю, насколько велики строки до его запуска, поэтому я и не использовал его. Очевидно, что если я использую char*[], я получаю ошибку сегмента, когда пытаюсь получить доступ к элементам char*.

Вот фрагмент кода

//input
char *line = "echo hello there what is";
int count = 0;

//store arguments
char args[6][10];
int argCount = 0;

//store temp string from input
char temp[100];
int tempCount = 0;

//word(string) size
int wordSize = 0;

/*
 Here I iterate over the input, storing each string I find in args
 all the above variables help me do that.
 */

execvp(args[0], args);

printf("Error: It didnt work\n");

Надеюсь, это ясный и правильный вопрос, дайте мне знать, если вы хотите, чтобы я добавил код моего превращения ввода в args.

Ответы [ 3 ]

3 голосов
/ 04 мая 2019

Массив массивов char отличается от массива указателей на массивы char. execvp() ожидает последний, с нулевым указателем в качестве последнего элемента, передавая первый, имеет неопределенное поведение.

Вы должны создать массив указателей, выделенных из кучи или определенных с автоматическим хранением ( в стеке ), инициализировать его указателями на строки аргументов и передать этот массив в execvp().

Также обратите внимание, что echo является одновременно внутренней командой оболочки и исполняемым файлом в пути.

Вот ваш фрагмент кода, модифицированный соответствующим образом (без кода синтаксического анализа, который по-прежнему остается вашим писать):

    //input "echo hello there what is";
    //arguments array
    char *args[6];

    /*
     * Here you should iterate over the input, storing each string you find 
     * on the command line into `args` and terminate with a null pointer...
     */

    args[0] = "echo";
    args[1] = "hello";
    args[2] = "there";
    args[3] = "what";
    args[4] = "is";
    args[5] = NULL;

    execvp(args[0], args);
1 голос
/ 04 мая 2019

Вы можете использовать два массива:

char real_args[6][10];  // Six strings of up to nine characters each
...
char *args[] = {
    real_args[0],
    real_args[1],
    real_args[2],
    real_args[3],
    real_args[4],
    real_args[5],
    NULL  // Must be terminated by a null pointer
};

Использовать real_args для фактических аргументов, а затем передать args в execvp.

0 голосов
/ 05 мая 2019

Хорошо, я разработал, как использовать char*[] вместо char[][] и успешно поместил его в execvp().

Примечания к коду ниже: я отслеживаю длину текущей строки, которую я перебираю в wordSize.

    //input
    char* line = "echo hello there what is";
    int count = 0;

    //store arguments
    char* args[10];
    int argCount = 0;

    //store temp string from input
    char temp[100];
    int tempCount = 0;

    //word size
    int wordSize = 0;

    while(line[count] != '\0')
    {
        if (line[count] == ' ' || line[count + 1] == '\0')
        {
            /*
              As I don't know how big each string will be, I can 
              allocate it here as I know how big the string is through wordSize
            */
            args[argCount] = malloc(sizeof(char)*(wordSize +1));
            .
            .
            .
        }
    }



    //terminate args with 0
    args[argCount] = 0;

    execvp(args[0], args);

    printf("Error: It didnt work\n");

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...