寻找一种从配置文件中读取参数的方法我找到了一种很好的方法来做到这一点但事情是当我尝试计算线条时发生了一些非常奇怪的事情。
这是代码:
FILE *file = fopen("config", "r");
char line[100];
int linenum = 0;
//int foo; Uncomment and it starts to working, doesn't matter if you rename it.
while(fgets(line, sizeof(line), file) != NULL) {
char option[4];
char arg[100];
if (line[linenum] == '#')
continue;
linenum++;
if (sscanf(line, "%s %s", option, arg) != 2)
fprintf(stderr, "Syntax error, line %i\n", linenum);
配置文件如下所示:
#config file
option1
option2
option3
结果是:
Syntax error, line 1
Syntax error, line 0
Syntax error, line 0
但是如果我在while循环之前声明一个带有任何名称的int变量,它就会开始工作!
结果是:
Syntax error, line 1
Syntax error, line 2
Syntax error, line 3
世界上到底发生了什么?我的思绪会被打击,也许这是一种愚蠢的事情,但我认为没有任何理由。
答案 0 :(得分:3)
您的option
数组太小(char option[4]
),因此sscanf
会覆盖其他内容。未定义的行为。
通常,当奇怪的事情无缘无故地发生时(就像你声明一个无关的变量一样“工作”),这是因为内存问题。由于您提到gcc
,因此您可能需要查看valgrind
。
答案 1 :(得分:1)
至少看起来像这部分:
if (line[linenum] == '#') continue;
linenum++;
将无法提供所需的结果,因为您正在检查行开头的注释字符。
答案 2 :(得分:0)
if (sscanf(line, "%s %s", option, arg) != 2)
这会溢出option
数组并覆盖linenum
对象。
答案 3 :(得分:0)
每当你看到这样的奇怪行为时,你应该开始寻找内存溢出错误。典型症状包括:
在这种情况下,正如其他答案所指出的那样,您有两个潜在的与内存相关的错误:
第if (line[linenum] == '#') continue;
行
应为if (line[0] == '#') continue;
否则,linenum > 99
时索引无效。
行if (sscanf(line, "%s %s", option, arg) != 2){
将超出option
和arg
变量。 (您看到的错误是因为文本(例如 option1
)超过4个字符并溢出option
。您可以通过多种方式解决此问题:
option
的大小。您需要知道输入字符串的最大长度才能选择合适的大小。option
的字符数:if (sscanf(line, "%3s %99s", option, arg) != 2){
arg
将包含option
中字符串的其余部分(如果它被截断)。a
修饰符告诉sscanf
在读取字符串时为字符串分配内存:char **str1, **str2;
if (sscanf(line, "%as %as", &str1, &str2) != 2){