1

我做了一个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 的菜鸟,很抱歉给您带来不便。

4

2 回答 2

3

看到这个黑客:

... strlen(buff) - 2)

随着阅读“适用于 Windows 而不适用于 Linux\r\n ”,我的感觉告诉我,代码会因为 windows 换行符和 Linux换行符是这样的事实而绊倒\n,也就是说,在 windows 上它们是 2char秒,char在 Linux 上是 1 长.

我的建议是在处理读取的“其余”行之前添加一些(可能是特定于平台的)代码以摆脱任何换行符。

一些显示如何完成的代码在这里:https ://stackoverflow.com/a/16000784/694576

添加一般建议:如果您将自己的写作陷入可能是正值的陷阱strlen(..) - xx如果这确实是您需要的,请务必三思而后行,因为如果这种减法的结果变成负值,尤其是如果您使用 (正如你应该做的那样)作为结果类型。然后它将下溢。由于这种结构通常用于稍后索引另一个字符串,这将发生在一个数字上...... - 其余的是“流血”历史。size_t

于 2014-05-20T13:23:52.600 回答
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) {... 
于 2014-05-20T12:55:41.690 回答