意外的memcmp返回值

时间:2014-05-20 12:26:15

标签: c string memcmp

我制作了一个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中的菜鸟,对此造成的不便表示歉意。

2 个答案:

答案 0 :(得分:3)

看到这个黑客:

... strlen(buff) - 2)

随着阅读“在Windows上运行而不在Linux上运行”我的感觉告诉我代码绊倒了windows新行是\r\n和Linux新行的事实是\n,在Windows上,它们在Linux上为2 char s和char长。

我建议解决这个问题是添加一些(可能是平台特定的)代码,以便在处理读取行的“其余”之前删除任何新行。

有些代码显示了可能会如何完成:https://stackoverflow.com/a/16000784/694576

添加一般建议:如果你自己写strlen(..) - x x可能是正值总是三思而后行真的你需要什么,因为如果这种减法的结果变得消极,这是进入灾难的一种方式,特别是如果你使用(你应该)size_t作为结果类型。它会下流。因为这样的构造通常用于稍后索引另一个字符串,所以这将发生 BIG 数字...... - 其余的是“流血”历史。

答案 1 :(得分:0)

恕我直言,一行的操作太多,尝试拆分并检查

if (memcmp (p + 1, section, strlen (buff) - 2) == 0)

char *lefthand = p + 1;
size_t comaprecnt = strlen (buff) - 2;
if ( memcmp(lefthand, section, comparecnt) == 0) {...