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では機能しません」を読むとともに、私の感覚では、Windowsの改行は で\r\nあり、Linuxの改行\nは であり、Windowsでは2であり、Linuxではchar1のchar長さであるという事実にコードがつまずいていることがわかります.

これを回避するための私のアドバイスは、読み取った行の「残り」を操作する前に、改行を取り除くためにいくつかの (おそらくプラットフォーム固有の) コードを追加することです。

これがどのように行われるかを示すコードは次のとおりです: https://stackoverflow.com/a/16000784/694576

一般的なアドバイスを追加する:正の値である可能性があると書いstrlen(..) - xている場合は、これが本当に必要かどうかを常によく考えてください。これは、この減算の結果が負になると、特に (必要に応じて)結果の型として。するとアンダーフローします。そして、そのような構成は通常、後で別の文字列にインデックスを付けるために使用されるため、これは大きな数字で発生します...-残りは「出血」履歴です。xsize_t

于 2014-05-20T13:23:52.600 に答える
0

IMHO 1行の操作が多すぎます。分割して確認してください

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 に答える