0

char[][] 型 (別名、文字列の配列) のデータを使用して execvp を実行しようとしています。これで execvp() 、文字列へのポインターを最初のパラメーターとして受け取り、次に文字列の配列へのポインターを 2 番目のパラメーターとして受け取ることがわかりました。以下で動作させるための文字列と文字列-私が試したものはすべて互換性がないと見なされます!

どんな助けにも感謝します:)-コードを少しコンパクトにするためにヘッダーを削除しました!

struct userinput {
    char anyargs[30][30]; //The tokenised command
};

int main() {

    struct userinput input = { { { 0 } } }; //I believe is valid to set input to 0's
    struct userinput *inPtr = &input; //Pointer to input (direct access will be unavailable)

    strcpy(inPtr->anyargs[0], "ls"); //Hard code anyargs to arbitary values
    strcpy(inPtr->anyargs[1], "-lh");

    char (*arrPointer)[30]; //Pointer to an array of char *
    arrPointer = &(inPtr->anyargs[0]);

    printf("arrPointer[0]: %s, arrPointer[1]: %s\n", arrPointer[0],
            arrPointer[1]);

    printf("At exec case; ");
    execvp( arrPointer[0], arrPointer);
    perror("Command not recognised"); //Prints string then error message from errno

    return 0;
}
4

2 に答える 2

2

The execvp() expects as second argument a char *const argv[]. This means an array of pointers to char. This is different from a char[30][30] which is represented in memory as 30x30 contiguous chars (so no pointer).

To solve this, define your structure

struct userinput {
    char *anyargs[30]; //space for 30 char* pointers
};

You could as well define anyargs as char** and initalize if dynamically with (char**)calloc(number_of_args+1,sizeof(char*))

Later, assign directly the pointers:

inPtr->anyargs[0] = "ls"; //Hard code (or use strdup() )
inPtr->anyargs[1] = "-lh";
inPtr->anyargs[2] = NULL; // end of the argument list !!!
char **arrPointer; //Pointer to an array of char *
arrPointer = inPtr->anyargs;

Edit: Caution: "The array of pointers must be terminated by a NULL pointer.".

于 2014-11-09T17:34:06.137 に答える
2

char[][]Cのようなものはありません。execvpへのポインタの配列が必要const charです。これは、 または のいずれかとして記述できchar * const *ますchar * const []

ただし、ポインタの配列ではなく、長さ 30 文字の配列の配列があります。この 2 つのタイプは互換性がなく、互換性がなく、どちらの方向にも相互に変換できません。

この行で

char (*arrPointer)[30]; //Pointer to an array of char *

char* の配列へのポインターを誤って宣言しようとしています。代わりに宣言したのは へのポインタであり、期待char[30]されるものとは大きく異なります。execvp

次の行

arrPointer = &(inPtr->anyargs[0]);

へのポインターを使用して の配列へのポインターを初期化することを目的としてchar*いますchar[30]。これは、 の配列へのポインターを宣言したとしてもおそらく正しくありchar*ません。代入の右側は の配列へのポインターではなく、ポインターだからですchar*。キャスト、インデックス、アドレス、char[30]および逆参照のシーケンスは、互いに変わりません。

への 30 個のポインターの配列は、次のcharように宣言されます。

char* arguments[30];

へのポインターの動的サイズの配列は、次のcharように作成されます。

char** arguments = calloc (nargs, sizeof(char*));

を呼び出す場合は、これらのいずれかを使用する必要がありますexecvp

いずれの場合も、ポインターの配列内の各ポインターは、個々の NUL で終了する文字配列 (おそらく配列の要素char[30][30]) を指すように初期化する必要があり、最後のポインター (渡したいすべての引数の後の 1 つ) を次のように設定する必要があります。ヌル。( a で NULL を見つけることをどのように期待していたのだろうかchar[30][30])。

于 2014-11-09T17:52:35.500 に答える