1

一直在这里搜索,但如果这篇文章是重复的,请原谅我......我只是想澄清一些我不确定的事情......

首先,让我介绍一下我的想法:

  • 将要求用户输入命令(类似于命令行/shell 命令)。
  • 该命令将作为由空格分隔的字符串接收/输入。
  • 接下来字符串将被标记化(拆分),单词的数量将被计算在内。
  • 有了这个数量的单词,我将不得不创建一个动态的多维字符串数组,其中字符串的大小/数量是我们计算的单词数。

例子:

我叫 1234123 123123

该命令中的单词/字符串数为 4,因此字符串指针的数量将被动态分配。

我希望将此字符串存储在动态多维数组中,其中:

char ** arguments;
int count;

我想访问参数数组中的值:

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

我的问题是

当我尝试在我的主函数中访问这些变量时,arguments变量中的值是垃圾,并且count变量继续递增,因为我知道我已将count变量初始化回 0。

如果我做了一些模糊或错误的事情,你可以检查我的代码。谢谢!


以下是我能够创建的我认为有用的代码:

/* 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 回答