首页 文章

C中的文件读取,随机错误

提问于
浏览
1

感谢大家到目前为止您的意见和建议!

Additionally:

在进一步测试和玩弄后,似乎对FileReader的单独调用成功 . 但是多次调用FileReader(这些可能是FileReader的单独版本)会导致问题发生 .

End Add

你好,

我有一个非常不寻常的问题[请完整阅读:这很重要](Code :: Blocks编译器,Windows Vista Home)[没有可复制的代码]和C文件读取功能(fread,fgetc) . 现在,通常,文件读取功能正确地将数据加载到自分配和自解除分配的字符串(并且它不是字符串的问题),但这是奇怪的(以及量子物理学适合的地方):

错误捕获语句报告EOF发生得太早(在文本文件开头的评论部分中的IE,它加载了's loading). Printing out the string [after it's)报告确实,它终止于24(文件大约300个字符长) EOF: This is where it goes whacky

暂时检查Read - > _ base报告整个(~300)字符被加载 - 24处没有EOF . 困惑,[给它是一个fgetc循环]我添加了一个printf来显示每个char [作为%d所以我可以发现 - 1 EOF]每一步都可以看到它在做什么,并对其进行了修改,因此它只是一个字符 . 它循环很好,达到~300而不是24 - 但稍后随机冻结 . 但是,当我删除printf时,它再次终止于24并被错误捕获语句捕获 .

Summary :所以,基本上:我有一个受量子物理学影响的错误:当我试图观察我从fgetc通过printf获得的字符时,问题(早期EOF终止于24)消失了,但是当我停止查看它,错误捕获语句报告提前终止 .

更奇怪的是,这不是第一次发生 . Fread有类似的问题,我无法弄清楚原因,并用fgetc循环替换它 .

[代码无法真正提供,因为代码库的大小为5个 Headers ] .

片段:

int X = 0; 
int C = 0; 
int I = 0;

while(Copy.Array[X] != EOF)
{
    //Copy.Array[X] = fgetc(Read);
    C = fgetc(Read);
    Copy.Array[X] = C;
    printf("%d %c\n",C,C); //Remove/add this as necessary
    if(C == EOF){break;}
    X++;
}

侧注:将其分解为最简单的格式不会重现错误 .

5 回答

  • 1

    您可能正在进行一些堆损坏 . 没有看到代码就无法说出来 .

  • 5

    这是本书中最古老的错误 .

    您不能使用 char 类型的变量来读取字符(!),因为 EOF 常量不适合 .

    你需要:

    int C;
    

    此外, while 条件看起来很可怕,你在循环中递增 X ,然后检查(新)位置,是否正确初始化?在开始循环之前,您没有显示如何设置 Copy.Array .

    我建议完全删除它,这是非常奇怪的代码 .

    事实上,我不明白你为什么要循环阅读单个字符,为什么不只是使用 fread() 来阅读你需要的东西呢?

  • 0

    首先,展开的答案是一个有效的观点,虽然我不确定它是否解释了你所看到的问题 .

    其次,

    printf("%d %c\n",C,C); //Remove/add this as necessary
    

    可能是个问题 . %d%c 格式说明符期望int为参数,您只传递char . 根据您的编译器,这可能意味着它们太小 .


    这就是我认为问题所在:

    你是如何分配Copy.Array的?在开始之前,您是否确保其所有元素都归零?如果你malloc它(malloc只是留下它返回的内存中的垃圾)并且一个元素恰好包含 0xFF ,你的循环将过早退出,因为你的while条件测试了Copy.Array [X]之前你已经放置了一个字符地点 .

    这是少数情况之一,我允许自己将一个赋值放在条件中,因为模式

    int c;
    while ((c = fgetc(fileStream)) != EOF)
    {
        doSomethingWithC(c);
    }
    

    真的很普遍


    Edit

    只需阅读您的“另外”评论 . 我认为你很可能超出输出缓冲区 . 我认为您应该将代码更改为:

    int X = 0; int C = 0; int I = 0;
        while(X < arraySize && (C = fgetc(Read)) != EOF)
        {
            Copy.Array[X] = C;
            printf("%d %c\n", (int)C, (int)C);
            X++;
        }
        printf("\n");
    

    请注意,我假设您有一个名为 arraySize 的变量,该变量设置为可以写入数组但不会超出它的字符数 . 另请注意,我没有将EOF写入您的阵列 .

  • 0

    不确定这是你的错误,但是这段代码:

    C = fgetc(Read);
    Copy.Array[X] = C;
    if(C == EOF){break;}
    

    意味着你要将 EOF 值添加到你的数组中 - 我想要这样做,特别是因为你的数组大概是 charEOFint ,所以你实际上最终会得到一些其他的值(这可能会弄乱)以后循环等) .

    相反,我建议你改变顺序,所以 C 只有在你知道它不是 EOF 时才被放入数组中:

    C = fgetc(Read);
    if(C == EOF){break;}
    Copy.Array[X] = C;
    
  • 0

    虽然这不是我称之为“完整”的答案(因为bug仍然存在),但这确实解决了“观察者效应”元素:我发现,由于某种原因,printf以某种方式'修复'代码,并使用std :: cout似乎(好吧,我不能说'修复'问题)阻止了观察者效应的发生 . 也就是说,使用std :: cout而不是printf(因为printf是观察者效果的起源) .

    在我看来,printf在较低级别的内存中执行某些操作,似乎部分纠正了内存分配错误 .

相关问题