我制作了一个 INI 文件解析器,它在 Windows 上运行良好但在 Linux 上运行不佳,问题来自 memcmp 函数,它不应该返回 0,我已经用 printf 检查过和 strlen,(我也尝试改用 strncmp,它返回了不同的值,但仍然不同于 0)但找不到问题出在哪里。
代码如下:
#define INI_KEY_LENGTH 128
#define BEGIN '['
#define SEP '='
#define COMMENT ';'
static char configfilename[255];
static char * str_dup (const char * str){
char * dup = NULL;
if (str != NULL){
size_t size = strlen (str) + 1;
dup = malloc (size);
if (dup != NULL){
memcpy (dup, str, size);
}
}
return dup;
}
static void str_finalize (char * str){
char * p = strchr (str, '\n');
if (p != NULL){
*p = '\0';
}
}
static char * get (const char * filename, const char * section, const char * key){
char * ret = NULL;
char buff [INI_KEY_LENGTH];
FILE * file = NULL;
int opened = 0;
file = fopen (filename, "r");
if (file != NULL){
while ((fgets (buff, INI_KEY_LENGTH, file)) != NULL){
str_finalize (buff);
if (! opened && buff [0] == BEGIN){
char * p = buff;
// Don't work here
if (memcmp (p + 1, section, strlen (buff) - 2) == 0){
opened = 1;
continue;
}
}
else if (opened){
if (buff [0] == BEGIN){
opened = 0;
break;
}
if(buff [0] != COMMENT){
if (strstr (buff, key) != NULL){
char * p = strchr (buff, SEP);
if (p != NULL){
p++;
ret = str_dup (p);
break;
}
}
}
}
}
fclose (file);
}
return ret;
}
int init_iniFile (const char * filename){
int ret = 0;
FILE * file;
if ((file = fopen(filename, "r")) != NULL){
fclose(file);
strcpy(configfilename, filename);
ret = 1;
}
return ret;
}
char * get_string (const char * section, const char * key){
return get (configfilename, section, key);
}
我怀疑这个错误是愚蠢的,但我是 C 语言的菜鸟,对于给您带来的不便,我们深表歉意。
最佳答案
看到这个黑客:
... strlen(buff) - 2)
随着阅读“在 Windows 上工作但在 Linux 上不工作”,我的感觉告诉我代码因 Windows 换行符是 \r\n
和 Linux 换行符是 \n
,在 Windows 上它们是 2 个 char
和一个 char
在 Linux 上。
我建议解决这个问题是添加一些(可能是特定于平台的)代码以在处理读取的“其余”行之前删除任何换行符。
一些代码显示了如何完成这里:https://stackoverflow.com/a/16000784/694576
添加一般性建议:如果您陷入编写 strlen(..) - x
且 x
可能为正值的困境,请始终思考如果这确实是您需要的,则两次,因为如果此减法的结果变为负值,这将导致灾难,特别是如果您正在使用(正如您应该使用的那样)size_t
作为结果类型。它将下溢。由于这种构造通常用于以后索引另一个字符串,这将发生在一个大数字...... - 其余的是“流血”历史。
关于c - 意外的 memcmp 返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23759811/