为什么不能再次使用?

时间:2018-05-07 20:42:31

标签: c getopt

我需要逐行读取字符串以找出事件日志的逻辑。我有下面的代码测试逐行读取字符串,用空格字符分隔每一行,将每个标记存储到char *argv[],并在getopt中使用它。

// Format: (-A | -L) (-E | -G) <Name> -T <Timestamp> [-R <Room ID>]
int main(int argc, char **argv)
{
    const char *testString = "-A -E bob -T 1 -R 1\n-L -G   John -T 2  -R  2   \n -A   -G Me -T    02   ";
    const char *curr_line = testString;

    // read line by line
    while (curr_line)
    {   
        char *token;    // token for strtok()
        char *argv[9];  // mock argv
        int argc = 1;   // argument counter
        int opt = -1;   // for getopt()

        // for line splitting
        const char *next_line = strchr(curr_line, '\n');
        int curr_line_len = next_line ? (next_line - curr_line) : strlen(curr_line);

        int test_index = 0; // for testing

        // allocate space for current line
        char *tempStr = (char *)malloc(curr_line_len + 1);

        if (tempStr)
        {

            strncpy(tempStr, curr_line, curr_line_len);
            tempStr[curr_line_len] = '\0';
            memset(argv, '\0', 9);
            printf("Line: %s\n", tempStr);

            token = strtok(tempStr, " ");
            while (token != NULL)
            {
                argv[argc] = token;
                argc++;
                token = strtok(NULL, " ");
            }
            argv[0] = "test";

            // for testing 
            while(strcmp(argv[test_index], "\0") != 0) {
                printf("Token: %s\n",argv[test_index]);
                test_index++;
            }
            printf("argc is %d\n", argc);

            while ((opt = getopt(argc, argv, "ALE:G:T:R:")) != -1)
            {
                switch (opt)
                {
                case 'A':
                    printf("A\n");
                    break;
                case 'L':
                    printf("L\n");
                    break;
                case 'E':
                    printf("E %s\n", optarg);
                    break;
                case 'G':
                    printf("G %s\n", optarg);
                    break;

                case 'T':
                    printf("T %s\n", optarg);
                    break;
                case 'R':
                    printf("R %s\n", optarg);
                    break;
                default:
                    printf("unknown option\n");
                }
            }

            free(tempStr);
        }
        else
        {
            printf("malloc error\n");
            exit(255);
        }

        curr_line = next_line ? (next_line + 1) : NULL;
    }
    return 0;
}

现在的问题是getopt仅在第一个循环上运行。它会自动终止所有后续行。我写的测试代码打印出以下输出:

Line: -A -E bob -T 1 -R 1
Token: test
Token: -A
Token: -E
Token: bob
Token: -T
Token: 1
Token: -R
Token: 1
argc is 8
A
E bob
T 1
R 1
Line: -L -G   John -T 2  -R  2
Token: test
Token: -L
Token: -G
Token: John
Token: -T
Token: 2
Token: -R
Token: 2
argc is 8
Line:  -A   -G Me -T    02
Token: test
Token: -A
Token: -G
Token: Me
Token: -T
Token: 02
Token: 2
argc is 6

您可以看到每行都被正确读取,并且令牌被很好地划分。但getopt仅适用一次。我倾向于某种类型的内存分配问题,但我不知道这里有什么问题。

注意argv是以9启动的,因为参数的参数不能超过9个。

0 个答案:

没有答案