0

私はCポインターが初めてで、コマンドラインでプロセスを実行してpidを取得しようとしています。コマンドラインを使用するsystem()、sh()などのいずれもpidを返さないため、execve()を使用することにしました。ただし、コマンドラインを解析して文字列配列にする必要があります。

既存のソリューションをいくつか見つけましたが、機能させることができませんでした。だから、私は自分自身を書きました。私のテスト プログラムでは動作しますが、実際のプログラムではセグメンテーション エラーが発生します。どこが間違っているのか、誰か教えてもらえますか? コードは次のとおりです。

void cmdline_to_argv(const char* cmd_line, char*** argv, int* argc){
    int len, i, count, spc;
    char *s,*d;
    /* make a copy to play with */
    char *cmd_line1 = strdup(cmd_line);

    /* count items to deal with and trim multiple spaces */
    d = s = cmd_line1; spc = 1; count = 0; len=strlen(cmd_line1);
    for (i=0; i<len;i++,s++) {
        switch (*s) {
        case ' ':
            if (spc) continue;
            *d++ = '\0'; /* replace spaces with zeroes */
            spc = 1;
            break;
        default:
            if (spc) { count++; spc = 0; }
            *d++ = *s;
        }
    }
    (*d++) = '\0'; /* line termination */
    /* reallocate copy to correct size */
    cmd_line1 = realloc( cmd_line1, d - cmd_line1);
    /* allocate array of poiters */
    *argv = (char**) malloc(sizeof(char*) * (count+1));
    argv[count] = NULL;
    /* scan line again to find all lines starts and register */
    s = cmd_line1;
    for (i=0; i<count; i++) {
        (*argv)[i] = s;
        while (*(s++)) ;
    }
    *argc = count;
}

そして、私がそれを呼ぶ方法があります:

char **chargv = NULL;
int chargc;

/* parse line to argument array */
cmdline_to_argv(cmdline, &chargv, &chargc);

ここで、配列を割り当てて書き込むポインター操作ですべての問題が発生すると思います。どうすれば正しいですか?

4

2 に答える 2

2

質問は締め切りました。解決策が見つかりました。トリッキーなポインター宣言構文が解決されました。これが作業中のものです。

ありがとうございます。:-|

 void cmdline_to_argv(const char* cmd_line, char ***argv, int* argc){
    int i, spc;
    size_t len;
    char *s,*d;
    /* make a copy to play with */
    char *cmd_line1 = strdup(cmd_line);

    /* count items to deal with and trim multiple spaces */
    d = s = cmd_line1; spc = 1; *argc = 0; len=strlen(cmd_line1);
    for (i=0; i<len;i++,s++) {
        switch (*s) {
        case ' ':
            if (spc) continue;
            *d++ = '\0'; /* replace spaces with zeroes */
            spc = 1;
            break;
        default:
            if (spc) { (*argc)++; spc = 0; }
            *d++ = *s;
        }
    }
    (*d++) = '\0'; /* line termination */
    /* calc actual size */
    len = d - cmd_line1;
    /* allocate array of poiters */
    *argv = (char**) malloc(sizeof(char*) * ((*argc)+1) + len);
    (*argv)[*argc] = (char*) NULL;
    d = (char*) &(*argv)[(*argc)+1];
    memmove(d, cmd_line1, len);
    free(cmd_line1);
    cmd_line1 = d;
    /* scan line again to find all lines starts and register */
    for (i=0; i<*argc; i++) {
        (*argv)[i] = d;
        while (*(d++)) ;
    }
}

/* deallocate array and strings */
void free_argv(char ***argv) {
    free(*argv); /* strings laying together at once after pointers array */
}
于 2013-03-05T19:15:42.667 に答える
1

ここを見ましたかhttps://www.kernel.org/doc/man-pages/online/pages/man2/getpid.2.html あなたが望むのは getpid() だと思いますが、もっと何かを求めているかもしれません。

于 2013-03-04T18:50:39.060 に答える