1

ここを検索してきましたが、この投稿が重複している場合はご容赦ください...わからないことを明確にしたいだけです...

まず、私が考えていることを紹介します。

  • ユーザーはコマンドを入力するように求められます(コマンドライン/シェルコマンドと同様)。
  • コマンドは、空白で区切られた文字列として受信/入力されます。
  • 次に、文字列がトークン化(分割)され、単語数がカウントされます。
  • その数の単語が手元にあるので、文字列の動的な多次元配列を作成する必要があります。ここで、文字列のサイズ/数は、カウントした単語の数です。

例:

私の名前は1234123123123

そのコマンド内の単語/文字列の数は4であるため、文字列ポインタの数は動的に割り当てられます。

この文字列を動的な多次元配列に格納する必要があります。ここで、

char ** arguments;
int count;

引数配列内の値に次のようにアクセスしたいと思います。

for(i = 0; i < count; i++)
    printf("%s", arguments[i]);

私の問題は

main関数でこれらの変数にアクセスしようとすると、arguments変数内の値はガベージであり、count変数を0に初期化したことを認識して、 count変数はインクリメントし続けます。

私が漠然としたことや間違ったことをしたかどうか、私のコードをチェックすることができます。ありがとう!


これが私が有用だと思う場所で作成できたコードです:

/* This function counts the number of words inside the command input. */
int word_count(char * str)
{
    int i, ctr;

    for(ctr = i = 0; str[i] != '\0'; i++)
    {
        while(isspace(str[i]))
            i++;

        if(str[i] != '\0')
        {
            ctr++;

            while(str[i] != '\0' && ! isspace(str[i]))
                i++;
        }
    }

    return ctr;
}

/* This function splits the strings inside the command. */
void split_command(int count, char *** argv, char * command)
{
    char buffer[31];
    int i, j, k;

    *argv = (char **) malloc(sizeof(char *) * count);

    for(i = k = 0; command[i] != '\0'; i++)
    {
        while(isspace(command[i]))
            i++;

        if(command[i] != '\0')
        {
            for(j = 0 ;j < 30 && command[i] != '\0' && ! isspace(command[i]); j++, i++)
                buffer[j] = (j != 0) ? command[i] : toupper(command[i]);

            buffer[j] = '\0';

            if(strlen(buffer) > 0)
            {
                (*argv)[k] = (char *) malloc(sizeof(char) * (strlen(buffer) + 1));
                strcpy((*argv)[k], buffer);
                k++;
            }
        }
    }
}

/* This function will re-initialize the provided arguments and counters. */
void prepare_command(int * count, char *** argv)
{
    int i;

    for(i = 0; i < *count; i++)
    {
        (*argv)[i] = NULL;
        free((*argv)[i]);
    }

    *count = 0;
    free(*argv);
    *argv = NULL;
}

主要

void main(void)
{
    char ** arguments, * command;
    int count, i;
    boolean end = False; // Assume I created an enum for boolean {False, True}

    /* Some initialization here. */
    count = 0;
    arguments = NULL;

    do
    {
        gets(command);
        count = word_count(command); /* This will return the number of strings inside the command */
        split_command(count, &arguments, command); /* This will allocate an array. */

        /* When I try to display something from here, some values are garbage and some are from the previous allocation...  */
        for(i = 0; i < count; i++)
            printf("%s\n", arguments[i]);

        prepare_command(&count, &arguments);
    }while(!end);

}

PS:私はstrtokを知っていますが、それを使いたくありません。また、ここのどのライブラリにもstrtok_rはありません。そこで、私はそれに似たものを処理するために独自の関数を作成しました。

これは長い投稿かもしれませんが、私を助けてほしいです...ありがとう!必要に応じて、この投稿を編集する必要があります。ありがとう、あなたが私にいくつかの光を当てることを願っています。:3 :)

4

1 に答える 1

0

私が使用しているコードスニペットは次のとおりです。

int parse_args(char** argv, char* data) {
    char c;
    int argc = 0;

    if (argv)
        *argv = data;

    int quoteopen = 0;
    int waitingnextarg = 1;
    for (;(c = *data); data++) {
        switch(c) {
            case '\n':
            case '\t':
            case ' ':
                if (!quoteopen) {
                    if (argv)
                        *data = 0;
                    waitingnextarg = 1;
                }
            break;
            case '"':
                if (argv)
                    *data = 0;
                if (quoteopen) {
                    waitingnextarg = 1;
                }
                quoteopen ^= 1;
            break;
            default:
                if (waitingnextarg) {
                    waitingnextarg = 0;
                    if (argv)
                        argv[argc] = data;
                    argc++;
                }
            break;
        }
    }

    return argc;
}

と電話する

int argc = parse_args(0, input);
char* argv[argc+1];
parse_args(argv, input);

注意: 入力文字列を変更します。これはメモリ割り当てを処理しませんが、事前に割り当てられたメモリのみを使用します。argv == NULL で呼び出された場合、カウントのみを行って argc を返します。有効なポインタ argv で呼び出された場合、入力文字列を変更して argv に入力します。入力文字列呼び出しのコピーを保持する必要がある場合は、

int argc = parse_args(0, input);
char input_copy[strlen(input) +1];
memcpy(input_copy, input, strlen(input) +1);
char* argv[argc+1];
parse_args(argv, input_copy);
于 2012-09-29T18:20:56.973 に答える