在C/ c++中与fopen的行为不一致

Inconsistent behaviour with fopen in C/C++

本文关键字:不一致 fopen 中与 c++      更新时间:2023-10-16

我正在使用一个多次打开相同文件的库。它检查文件的头以确保它是正确的格式。它打开文件的前1212次,它的行为是正确的。第1213次,从文件中读出的字节不同。有人能解释一下为什么会这样吗?

不幸的是,我不能做一个小的可重复的例子-它需要20分钟来运行到这一点。所以我想知道fopen是否有什么微妙之处我可能错过了,或者其他可能影响这次执行的东西。

代码如下。创建了许多类的实例,并且每个实例都使用相同的文件名调用initialize()。前1212次,输出为:

Expecting: '?'
?lon-1800????%@LYB1800????%@LYB100????%@LYB
                                       lat-900??p-2?%@HYB900??p-2?%@HYB10??p-2?%@HYB
                                                                                    ?   soilcode0   ??  ?-2?&@AYB12 ??  ?-2?&@AYB1  ??  ?-2?&@AYBmtemp-600??x.2?&@6YB600??x.2?&@6YB10??x.2?&@6YB
             ?mprec0???H2?&@.YB99999???H2?&@.YB1999???H2?&@.YB?msun0???A2?&@%YB1000???A2?&@%YB100???A2?&@%YB
?
Got: '?'
?lon-1800????%@LYB1800????%@LYB100????%@LYB
                                       lat-900??p-2?%@HYB900??p-2?%@HYB10??p-2?%@HYB
                                                                                    ?   soilcode0   ??  ?-2?&@AYB12 ??  ?-2?&@AYB1  ??  ?-2?&@AYBmtemp-600??x.2?&@6YB600??x.2?&@6YB10??x.2?&@6YB
             ?mprec0???H2?&@.YB99999???H2?&@.YB1999???H2?&@.YB?msun0???A2?&@%YB1000???A2?&@%YB100???A2?&@%YB
?

我最后一次得到:

Expecting: '?'
?lon-1800????%@LYB1800????%@LYB100????%@LYB
                                       lat-900??p-2?%@HYB900??p-2?%@HYB10??p-2?%@HYB
                                                                                    ?   soilcode0   ??  ?-2?&@AYB12 ??  ?-2?&@AYB1  ??  ?-2?&@AYBmtemp-600??x.2?&@6YB600??x.2?&@6YB10??x.2?&@6YB
             ?mprec0???H2?&@.YB99999???H2?&@.YB1999???H2?&@.YB?msun0???A2?&@%YB1000???A2?&@%YB100???A2?&@%YB
?
Got: '   lon       lat    year  

功能如下:

class Archive {
private:
FILE* pfile;
<snip>
    bool initialise(char* filename) {
    int i;
    unsigned char* pheader;
    if (pfile) fclose(pfile);
    pfile=fopen(filename,"rb");
    if (!pfile || pfile == NULL ) {
        printf("Could not open %s for inputn",filename);
        return false;
    }
    pheader=new unsigned char[CRU_1901_2002_HEADERSIZE-4];
    if (!pheader) {
        printf("Out of memoryn");
        fclose(pfile);
        pfile=NULL;
        return false;
    }
    ::rewind(pfile);
    fread(pheader,CRU_1901_2002_HEADERSIZE-4,1,pfile);
    printf( "Expecting: '%s'n", CRU_1901_2002_HEADER);
    for( int j = 0; j < CRU_1901_2002_HEADERSIZE-4;j++ )
        printf( "%c", CRU_1901_2002_HEADER[j]);
    printf( "nGot: '%s'n", pheader);
    for( int j = 0; j < CRU_1901_2002_HEADERSIZE-4;j++ )
        printf( "%c", pheader[j]);
    printf( "n");
    for (i=0;i<CRU_1901_2002_HEADERSIZE-4;i++) {
        if (pheader[i]!=CRU_1901_2002_HEADER[i]) {
            fclose(pfile);
            pfile=NULL;
            delete pheader;
            return false;
        }
    }
    delete pheader;
    ::rewind(pfile);
    fseek(pfile,CRU_1901_2002_HEADERSIZE+CRU_1901_2002_DATA_LENGTH*CRU_1901_2002_NRECORD,SEEK_CUR);
    recno=0;
    iseof=false;
    return true;
}
public:
Archive() {
    pfile=NULL;
}
Archive() {
    if (pfile) fclose(pfile);
}

你确定1213位有数据吗?或者,这些数据是正确的吗?
我建议你挂载一个超过1213条记录的文件,并做一个测试来确认在这个位置是否有读取错误。

原来这是因为打开的文件太多了。在其他地方更改程序以打开更少的文件可以修复它。

检查read返回1,除了最后一个,它返回0。

然而,我不明白为什么fopen在无法打开文件时返回非空文件指针。在测试代码中,它返回NULL,然后按预期捕获。