到目前为止,感谢大家的意见和建议!
此外:
经过测试和进一步调查后,似乎对FileReader的单独调用成功。但是多次调用FileReader(这些可能是FileReader的单独版本)会导致问题发生。
结束添加
您好,
我有一个非常不寻常的问题[请完整阅读:重要的是](Code :: Blocks编译器,Windows Vista Home)[没有可复制代码]和C文件读取功能(fread,fgetc)。现在,通常,文件读取功能正确地将数据加载到自分配和自解除分配的字符串(并且它不是字符串的问题),但这是奇怪的(以及量子物理学适合的地方):
错误捕获语句报告EOF发生得太早(IE正在加载的文本文件开头的注释部分内)。打印出字符串[加载后]确实报告确实太短(24个字符)(但它有足够的空间来容纳它[~400]并且没有分配问题)。 fgetc循环迭代器报告它终止于24(文件长度大约为300个字符)并带有EOF:这就是它的重要性:
暂时检查Read-> _base报告整个(~300)字符被加载 - 24处没有EOF。困惑,[给它是一个fgetc循环]我添加了一个printf来显示每个字符[作为%d所以我可以在每一步发现-1 EOF]所以我可以看到它正在做什么,并修改它所以它是一个单一的字符。它循环很好,达到~300而不是24 - 但稍后随机冻结。但是,当我删除printf时,它再次终止于24并被错误捕获的声明所捕获。
摘要: 所以,基本上:我有一个受量子物理学中“观察者效应”影响的错误:当我试图观察我从fgetc通过printf得到的字符时,问题(早期EOF终止于24)消失了,但是当我停止查看它,错误捕获语句报告提前终止。
更奇怪的是,这不是第一次发生。 Fread有类似的问题,我无法找出原因,并将其替换为fgetc循环。
[无法真正提供代码,因为代码库的大小为5个标题]。
段:
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++;
}
侧注:将其分解为最简单的格式不会重现错误。
答案 0 :(得分:5)
这是本书中最古老的错误,有点像。
您不能使用char
类型的变量来读取字符(!),因为EOF
常量不适合。
你需要:
int C;
此外,while
条件看起来很可怕,你在循环中递增X
,然后检查(新)位置,是否正确初始化?在开始循环之前,您没有显示Copy.Array
的设置方式。
我建议完全删除它,这是非常奇怪的代码。
事实上,我不明白为什么你要循环阅读单个字符,为什么不只是使用fread()
来阅读你需要的内容呢?
答案 1 :(得分:1)
首先,展开的答案是一个有效的观点,虽然我不确定它是否能解释你所看到的问题。
其次,
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);
}
真的很常见
修改强>
请阅读您的“另外”评论。我认为你很可能超出输出缓冲区。我认为您应该将代码更改为:
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写入您的阵列。
答案 2 :(得分:0)
您可能正在进行一些堆损坏。没有看到代码就无法说出来。
答案 3 :(得分:0)
不确定这是否是您的错误,但是此代码:
C = fgetc(Read);
Copy.Array[X] = C;
if(C == EOF){break;}
表示您要将EOF
值添加到数组中 - 我很确定您不希望这样做,尤其是因为您的数组可能是char
而EOF
是int
,所以你实际上会在那里得到一些其他值(这可能会破坏以后的循环等)。
相反,我建议您更改顺序,以便C
只有在您知道它不是EOF
后才会放入数组中:
C = fgetc(Read);
if(C == EOF){break;}
Copy.Array[X] = C;
答案 4 :(得分:0)
虽然这不是我称之为'完整'的答案(因为bug仍然存在),但这确实解决了'观察者效应'元素:我发现,由于某种原因,printf以某种方式'修复'代码并且使用std :: cout似乎(好吧,我不能说'修复'问题)阻止观察者效应的发生。也就是说,使用std :: cout而不是printf(因为printf是观察者效果的起源)。
在我看来,printf在较低级别的内存中执行某些操作,似乎部分纠正了内存分配错误。