我需要逐行读取字符串以找出事件日志的逻辑。我有下面的代码测试逐行读取字符串,用空格字符分隔每一行,将每个标记存储到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个。