【发布时间】:2012-10-27 15:05:58
【问题描述】:
我想从文件中读取字节然后重写它们。 我确实喜欢这样:
FILE *fp;
int cCurrent;
long currentPos;
/* check if the file is openable */
if( (fp = fopen(szFileName, "r+")) != NULL )
{
/* loop for each byte in the file crypt and rewrite */
while(cCurrent != EOF)
{
/* save current position */
currentPos = ftell(fp);
/* get the current byte */
cCurrent = fgetc(fp);
/* XOR it */
cCurrent ^= 0x10;
/* take the position indicator back to the last position */
fseek(fp, currentPos, SEEK_SET);
/* set the current byte */
fputc(cCurrent, fp);
}
对文件执行代码后,文件的大小在无限循环中增加。
我的代码有什么问题?
【问题讨论】:
-
您应该在写入 (
fputc()) 之后和下一次读取 (fgetc()) 之前执行fseek(),即使它只是fseek(fp, 0L, SEEK_CUR);。在更新流上,应该在读取和写入之间的每次更改之间进行类似搜索的操作。 -
@JonathanLeffler 为什么我必须进行 fseek?
-
因为 C 标准说如果你不这样做,行为是未定义的。未定义行为的危险之处在于它可能会在当前系统上执行您所期望的操作,但是如果编译器(或库)发生更改,或者您移动到另一台机器上,那么曾经工作的程序可能会停止工作 - 并且两种实现都完全正确。
-
ISO/IEC 9899:2011, §7.21.5.3
fopen函数。 ¶7 当文件以更新模式打开时(“+”作为上述模式参数值列表中的第二个或第三个字符),可以在关联的流上执行输入和输出。但是,如果没有对fflush函数或文件定位函数(fseek、fsetpos或rewind)的介入调用,则输出不应直接跟在输入之后,并且输入不应直接跟在输出之后没有对文件定位函数的干预调用,除非输入操作遇到文件结尾。 -
@JonathanLeffler 谢谢你的解释!
标签: c file fopen infinite-loop