【问题标题】:Inconsistent behaviour with fopen in C/C++在 C/C++ 中与 fopen 的行为不一致
【发布时间】:2011-04-25 18:14:56
【问题描述】:

我正在使用一个多次打开同一个文件的库。它检查文件的标题以确保它是正确的格式。打开文件的前 1212 次,它的行为正确。第 1213 次,从文件中读出的字节不同。谁能说明为什么会发生这种情况?

不幸的是,我无法制作一个可重现的小例子 - 运行到这一点需要 20 分钟。所以我想知道 fopen 是否有我可能遗漏的任何微妙之处,或者其他可能与这次执行有关的东西。

代码如下。创建了该类的许多实例,并且每个实例都使用相同的文件名调用了 initialise()。前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 input\n",filename);
        return false;
    }

    pheader=new unsigned char[CRU_1901_2002_HEADERSIZE-4];
    if (!pheader) {
        printf("Out of memory\n");
        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);
}

【问题讨论】:

  • 好吧,我们遇到了第一个障碍——pfile 是什么?由于这显然是 C++ 代码,因此我删除了 C 标签。
  • 我已经添加了 pfile 声明 - 感谢您了解它。
  • 目前 pfile 没有被初始化。这是真正的代码吗?
  • @mo-seph:您发布的代码没有任何问题。我的猜测是您的代码的其他部分存在指针错误或其他错误导致问题。此代码以我认为很难更改的方式使用指针。这让我认为您的代码中的其他地方可能存在指针错误。
  • fseek 和 fread 返回一个状态,但你忽略了它,修复它可能会给你一个关于正在发生的事情的线索。

标签: c++ file file-io fopen


【解决方案1】:

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

【讨论】:

  • 第1213次打开同一个文件,应该没有变化。
【解决方案2】:

事实证明,这是因为打开了太多文件。更改其他地方的程序以打开更少的文件可以修复它。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    • 1970-01-01
    • 2016-10-11
    相关资源
    最近更新 更多