验证C缺陷与陷阱 fwrite后面不能直接跟fread失败,求解释
C缺陷与陷阱 86页左右,有说fwrite后不能直接跟fread,但我在linux系统下验证失败,代码如下
#include <stdio.h>
int main()
{
FILE *fp =NULL;
char buffer[16] = "";
fp = fopen("test.ini", "r+");
if (NULL == fp)
{
return 0;
}
while(1 == fread(buffer, 8, 1, fp))
{
buffer[0] = 'a';
fseek(fp, -8, 1);
fwrite(buffer, 8, 1, fp);
}
return 0;
}
执行后,test.ini文件内容从:
111111112222222233333333
变为
a1111111a2222222a3333333
没有出现书本上说的出错问题,这是为什么
[解决办法]
与其看陷阱,不如看APUE,理解fread/fwrite底下的系统IO,是怎样一回事。
[解决办法]
推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。
不要把
fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待
和
fopen("...","...b");fread,fwrite,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待
弄混了
[解决办法]
这个陷阱在Linux和BSD没有的。
man fopen
Reads and writes may be intermixed on read/write streams in any order.
Note that ANSI C requires that a file positioning function intervene
betweenoutput and input, unless an input operation encounters end-of-
file. (If this condition is not met, then a read is allowed toreturn
the result of writes other than the most recent.) Therefore it is good
practice (and indeed sometimes necessary under Linux) to put an fseek
or fgetpos operation betweenwrite and read operations on such a
stream.This operation may be an apparent no-op (as in fseek(..., 0L,
SEEK_CUR) called for its synchronizing side effect.