c - 意外的 memcmp 返回值

标签 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 语言的菜鸟,对于给您带来的不便,我们深表歉意。

最佳答案

看到这个黑客:

... strlen(buff) - 2)

随着阅读“在 Windows 上工作但在 Linux 上不工作”,我的感觉告诉我代码因 Windows 换行符是 \r\n 和 Linux 换行符是 \n ,在 Windows 上它们是 2 个 char 和一个 char 在 Linux 上。

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

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

添加一般性建议:如果您陷入编写 strlen(..) - xx 可能为正值的困境,请始终思考如果这确实是您需要的,则两次,因为如果此减法的结果变为负值,这将导致灾难,特别是如果您正在使用(正如您应该使用的那样)size_t 作为结果类型。它将下溢。由于这种构造通常用于以后索引另一个字符串,这将发生在一个数字...... - 其余的是“流血”历史。

关于c - 意外的 memcmp 返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23759811/

相关文章:

c++ - C str 表示 - const char* 与 const unsigned char*

c - C中从1到100的素数

c - Ruby C 扩展开发人员的命名约定

c++ - 比 memcmp 更快的内存比较相等 16 字节 block

c - memcmp返回值,行为不一致

比较两个无符号字符结构和位域

c - 如何将结构数组初始化为空?

java - 未知输入字节长度转换为 int

c# - 字符串中的引号

.net - {0}、{1} 等是如何成为格式化字符串的标准的?