execvp(array[i], array) где массив [NUMBER][NUMBER] ошибка

Я пытаюсь отправить массив предопределенного размера пользовательского ввода в функцию execvp, однако я получаю предупреждение от компилятора. Существует соотношение текстового кода, которое требуется для stackru, поэтому я просто пытаюсь заполнить его, чтобы я мог отправить свое сообщение. Не беспокойтесь об этом, просто перейдите к приведенному ниже коду. Заранее спасибо!!!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define INPUTSIZE 50
#define INPUTCOUNT 10

int parseInput(char string[*][INPUTSIZE]);

void main(int argc, char **argv){
    char prompt = '#', shellInput[INPUTCOUNT][INPUTSIZE];
    pthread_t thread;
    pid_t processID;
    int rc;

    while(1){
        printf("%c", prompt);

        if(parseInput(shellInput)==EOF){
            exit(EXIT_SUCCESS);
        }

        processID = fork();
        if(processID == 0){
            execvp(shellInput[0], shellInput);
            printf("Uknown command\n");
        }


        printf("Nope.gif!\n");
        fflush(stdout);

    }
}

int parseInput(char string[INPUTCOUNT][INPUTSIZE]){
    char *inputString, *tempString;
    int i, status; 
    size_t bytecount = INPUTSIZE+1;

    inputString = (char *)malloc(INPUTCOUNT*INPUTSIZE);
    tempString = (char *)malloc(INPUTSIZE);
    status = getline(&inputString, &bytecount, stdin);

    tempString = strtok(inputString, " ");


    for(i = 0; i < INPUTCOUNT && tempString != NULL; i++){
        strncpy(string[i], tempString, INPUTSIZE);
        tempString = strtok(NULL, " \n\r");
    }
    strncpy(string[i], "NULL", sizeof(NULL));

    return status;
}

2 ответа

Дано

char shellInput[INPUTCOUNT][INPUTSIZE];

Тип переменной shellInput это "массив INPUTCOUNT массивы INPUTSIZEchars". В большинстве случаев shellInput автоматически преобразуется в тип "указатель на массив INPUTSIZEcharс "(char (*)[INPUTSIZE]). Это совсем не то же самое, что "массив указателей на char"((char *)[]), который является обязательным типом второго аргумента для execvp(),

(Технически, execvp() на самом деле объявлен принять const массив (изconst указатели), но допустимо передавать неконстантный.)

Похоже, вы хотите что-то еще, как это:

    char *shellInput[INPUTCOUNT + 1];

    /* ... */

int parseInput(char *string[]) {
    char *line = NULL;
    size_t line_len;
    ssize_t n_read = getline(&line, &line_len, stdin);
    char *token;
    int input_count = 0;

    if (n_read < 0) {
        return n_read;
    }

    for (token = strtok(line, " "); token && (input_count < INPUTCOUNT);
            token = strtok(NULL, " ")) {
        string[input_count++] = strdup(token);
    }
    string[input_count] = NULL;
    free(line);

    return n_read;
}

Обратите внимание, что родительский процесс должен освободить элементы shellInput (до, но не включая первый NULL) после каждого fork(), Кроме того, обратите внимание, что нет особой причины, почему вы не могли сделать shellInput иметь тип char **и учить parseInput() организовать для динамического выделения достаточно места для любого количества слов командной строки.

Ваш массив должен быть массивом указателей на char, а не массивом массивов char. Это связано с тем, что логический конец массива строк (он же char *), который вы должны передать exec, должен заканчиваться нулевым указателем. Если вы хотите исполнить ls -l myfile массив должен быть равен:

char *args[] = { "ls", "-l", "myfile", NULL };
Другие вопросы по тегам