c - 为什么不能再次使用getopt?
问题描述
我需要逐行读取字符串以找出事件日志的逻辑。我有下面的代码测试逐行读取字符串,用空格字符分隔每一行,将每个标记存储到 achar *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
只能工作一次。我倾向于某种类型的内存分配问题,但我不知道这里出了什么问题。
Noteargv
以 开头,9
因为参数不能超过 9 个参数。
解决方案
推荐阅读
- sql - 如何将具有重复值的行转换为列?
- docker - 火花泊坞窗图像
- python - Django 视图只呈现一页而不会呈现其余页面
- android - Android 在任何地图应用程序中自动显示从我的位置到给定位置的路线
- c# - 如何将图像从 api 读入 WPF 作为实时视频播放?
- c - AIX 7.2 GLib-GObject 信号传入无效
- swift - 是否可以在暂停的应用程序中运行预定的计时器?
- java - 如何摆脱空值异常
- java - Apache 晕厥修改 @XmlElement
- kubernetes - 如何使用 Prometheus Alert Manager 在 Kubernetes 中触发警报