tgbvc
发现 windows 的 fwrite 库函数有个严重的BUG。
[table=95%][tr][td][font=FixedSys][color=#000000]
[color=#0000CC]#[/color][color=#FF0000]include[/color] [color=#0000CC]<[/color]stdio[color=#0000CC].[/color]h[color=#0000CC]>[/color]
[color=#0000CC]#[/color][color=#FF0000]include[/color] [color=#0000CC]<[/color]conio[color=#0000CC].[/color]h[color=#0000CC]>[/color]
[color=#0000CC]#[/color][color=#FF0000]include[/color] [color=#0000CC]<[/color][color=#FF0000]string[/color][color=#0000CC].[/color]h[color=#0000CC]>[/color]
[color=#0000FF]void[/color] main[color=#0000CC]([/color] [color=#0000FF]void[/color] [color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]FILE[/color] [color=#0000CC]*[/color]stream[color=#0000CC];[/color]
[color=#0000FF]char[/color] ch [color=#0000CC]=[/color] [color=#FF00FF]'1'[/color][color=#0000CC];[/color]
[color=#0000FF]char[/color] buf[color=#0000CC][[/color]60[color=#0000CC]][/color] [color=#0000CC]=[/color] [color=#FF00FF]"123"[/color][color=#0000CC];[/color]
[color=#0000FF]int[/color] n [color=#0000CC]=[/color] 0[color=#0000CC];[/color]
stream [color=#0000CC]=[/color] [color=#FF0000]fopen[/color][color=#0000CC]([/color] [color=#FF00FF]"./Debug/fseek.txt"[/color][color=#0000CC],[/color] [color=#FF00FF]"w+"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]if[/color][color=#0000CC]([/color] stream [color=#0000CC]=[/color][color=#0000CC]=[/color] [color=#FF0000]NULL[/color] [color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"The file fseek.out was not opened/n"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]return[/color][color=#0000CC];[/color]
[color=#0000CC]}[/color]
[color=#0000FF]if[/color][color=#0000CC]([/color][color=#FF0000]strlen[/color][color=#0000CC]([/color]buf[color=#0000CC])[/color] [color=#0000CC]![/color][color=#0000CC]=[/color] [color=#FF0000]fwrite[/color][color=#0000CC]([/color]buf[color=#0000CC],[/color] 1[color=#0000CC],[/color] [color=#FF0000]strlen[/color][color=#0000CC]([/color]buf[color=#0000CC])[/color][color=#0000CC],[/color] stream[color=#0000CC])[/color][color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Error!/n"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]goto[/color] MAIN_GT1[color=#0000CC];[/color]
[color=#0000CC]}[/color]
[color=#FF0000]rewind[/color][color=#0000CC]([/color]stream[color=#0000CC])[/color][color=#0000CC];[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Position 1: %ld/n"[/color][color=#0000CC],[/color] [color=#FF0000]ftell[/color][color=#0000CC]([/color] stream[color=#0000CC])[/color] [color=#0000CC])[/color][color=#0000CC];[/color][color=#FF9900]//[]
[/color]
[color=#0000FF]if[/color][color=#0000CC]([/color]0 [color=#0000CC]![/color][color=#0000CC]=[/color] [color=#FF0000]fseek[/color][color=#0000CC]([/color]stream[color=#0000CC],[/color] 1[color=#0000CC],[/color] SEEK_CUR[color=#0000CC])[/color][color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Error! fseek != 0 /n"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]goto[/color] MAIN_GT1[color=#0000CC];[/color]
[color=#0000CC]}[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Position 2: %ld/n"[/color][color=#0000CC],[/color] [color=#FF0000]ftell[/color][color=#0000CC]([/color] stream[color=#0000CC])[/color] [color=#0000CC])[/color][color=#0000CC];[/color][color=#FF9900]//[]
[/color]
[color=#0000FF]while[/color][color=#0000CC]([/color]1 [color=#0000CC]=[/color][color=#0000CC]=[/color] [color=#FF0000]fread[/color][color=#0000CC]([/color][color=#0000CC]&[/color]ch[color=#0000CC],[/color] 1[color=#0000CC],[/color] 1[color=#0000CC],[/color] stream[color=#0000CC])[/color][color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Position 3: %ld, ch = %c/n"[/color][color=#0000CC],[/color] [color=#FF0000]ftell[/color][color=#0000CC]([/color] stream[color=#0000CC])[/color][color=#0000CC],[/color] ch [color=#0000CC])[/color][color=#0000CC];[/color][color=#FF9900]//[]
[/color]
[color=#0000FF]if[/color][color=#0000CC]([/color]0 [color=#0000CC]![/color][color=#0000CC]=[/color] [color=#FF0000]fseek[/color][color=#0000CC]([/color]stream[color=#0000CC],[/color] [color=#0000CC]-[/color]1[color=#0000CC],[/color] SEEK_CUR[color=#0000CC])[/color][color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Error! fseek != 0 /n"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]goto[/color] MAIN_GT1[color=#0000CC];[/color]
[color=#0000CC]}[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Position 4: %ld/n"[/color][color=#0000CC],[/color] [color=#FF0000]ftell[/color][color=#0000CC]([/color] stream [color=#0000CC])[/color] [color=#0000CC])[/color][color=#0000CC];[/color][color=#FF9900]//[]
[/color]
ch[color=#0000CC]+[/color][color=#0000CC]+[/color][color=#0000CC];[/color]
[color=#0000FF]if[/color][color=#0000CC]([/color]1 [color=#0000CC]![/color][color=#0000CC]=[/color] [color=#FF0000]fwrite[/color][color=#0000CC]([/color][color=#0000CC]&[/color]ch[color=#0000CC],[/color] 1[color=#0000CC],[/color] 1[color=#0000CC],[/color] stream[color=#0000CC])[/color][color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Error! fwrite != 0 /n"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]goto[/color] MAIN_GT1[color=#0000CC];[/color]
[color=#0000CC]}[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Position 5: %ld/n"[/color][color=#0000CC],[/color] [color=#FF0000]ftell[/color][color=#0000CC]([/color] stream [color=#0000CC])[/color] [color=#0000CC])[/color][color=#0000CC];[/color][color=#FF9900]//[]
[/color]
[color=#FF9900]//_getch();
[/color]
[color=#FF9900]// goto MAIN_GT1;
[/color]
[color=#FF9900]//n++;
[/color]
[color=#0000CC]}[/color]
MAIN_GT1[color=#0000CC]:[/color]
[color=#FF0000]fclose[/color][color=#0000CC]([/color] stream [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000CC]}[/color][/color][/font][/td][/tr][/table]
程序创建一个名为 fseek.txt 的空文件,然后向这个文件里写“123”三个字符,然后想把“23”改为“34”,可是为什么循环不停而且文件内容象下面不断增加?
134444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444443
原来windows的fwrite库函数有个严重的BUG,这样做就没事了:
[table=95%][tr][td][font=FixedSys][color=#000000]
[color=#0000CC]#[/color][color=#FF0000]include[/color] [color=#0000CC]<[/color]stdio[color=#0000CC].[/color]h[color=#0000CC]>[/color]
[color=#0000CC]#[/color][color=#FF0000]include[/color] [color=#0000CC]<[/color]conio[color=#0000CC].[/color]h[color=#0000CC]>[/color]
[color=#0000CC]#[/color][color=#FF0000]include[/color] [color=#0000CC]<[/color][color=#FF0000]string[/color][color=#0000CC].[/color]h[color=#0000CC]>[/color]
[color=#0000FF]void[/color] main[color=#0000CC]([/color] [color=#0000FF]void[/color] [color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]FILE[/color] [color=#0000CC]*[/color]stream[color=#0000CC];[/color]
[color=#0000FF]char[/color] ch [color=#0000CC]=[/color] [color=#FF00FF]'1'[/color][color=#0000CC];[/color]
[color=#0000FF]char[/color] buf[color=#0000CC][[/color]60[color=#0000CC]][/color] [color=#0000CC]=[/color] [color=#FF00FF]"123"[/color][color=#0000CC];[/color]
stream [color=#0000CC]=[/color] [color=#FF0000]fopen[/color][color=#0000CC]([/color] [color=#FF00FF]"./Debug/fseek.txt"[/color][color=#0000CC],[/color] [color=#FF00FF]"w+"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]if[/color][color=#0000CC]([/color] stream [color=#0000CC]=[/color][color=#0000CC]=[/color] [color=#FF0000]NULL[/color] [color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"The file fseek.out was not opened/n"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]return[/color][color=#0000CC];[/color]
[color=#0000CC]}[/color]
[color=#0000FF]if[/color][color=#0000CC]([/color][color=#FF0000]strlen[/color][color=#0000CC]([/color]buf[color=#0000CC])[/color] [color=#0000CC]![/color][color=#0000CC]=[/color] [color=#FF0000]fwrite[/color][color=#0000CC]([/color]buf[color=#0000CC],[/color] 1[color=#0000CC],[/color] [color=#FF0000]strlen[/color][color=#0000CC]([/color]buf[color=#0000CC])[/color][color=#0000CC],[/color] stream[color=#0000CC])[/color][color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Error!/n"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]goto[/color] MAIN_GT1[color=#0000CC];[/color]
[color=#0000CC]}[/color]
[color=#FF0000]rewind[/color][color=#0000CC]([/color] stream [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Position 1-----: %ld/n"[/color][color=#0000CC],[/color] [color=#FF0000]ftell[/color][color=#0000CC]([/color] stream[color=#0000CC])[/color] [color=#0000CC])[/color][color=#0000CC];[/color][color=#FF9900]//[]
[/color]
[color=#0000FF]while[/color][color=#0000CC]([/color]1 [color=#0000CC]=[/color][color=#0000CC]=[/color] [color=#FF0000]fread[/color][color=#0000CC]([/color][color=#0000CC]&[/color]ch[color=#0000CC],[/color] 1[color=#0000CC],[/color] 1[color=#0000CC],[/color] stream[color=#0000CC])[/color][color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Position 3: %ld, ch = %c/n"[/color][color=#0000CC],[/color] [color=#FF0000]ftell[/color][color=#0000CC]([/color] stream[color=#0000CC])[/color][color=#0000CC],[/color] ch [color=#0000CC])[/color][color=#0000CC];[/color][color=#FF9900]//[]
[/color]
[color=#0000FF]if[/color][color=#0000CC]([/color]0 [color=#0000CC]![/color][color=#0000CC]=[/color] [color=#FF0000]fseek[/color][color=#0000CC]([/color]stream[color=#0000CC],[/color] [color=#0000CC]-[/color]1[color=#0000CC],[/color] SEEK_CUR[color=#0000CC])[/color][color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Error! fseek != 0 /n"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]goto[/color] MAIN_GT1[color=#0000CC];[/color]
[color=#0000CC]}[/color]
ch[color=#0000CC]+[/color][color=#0000CC]+[/color][color=#0000CC];[/color]
[color=#0000FF]if[/color][color=#0000CC]([/color]1 [color=#0000CC]![/color][color=#0000CC]=[/color] [color=#FF0000]fwrite[/color][color=#0000CC]([/color][color=#0000CC]&[/color]ch[color=#0000CC],[/color] 1[color=#0000CC],[/color] 1[color=#0000CC],[/color] stream[color=#0000CC])[/color][color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Error! fwrite != 0 /n"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]goto[/color] MAIN_GT1[color=#0000CC];[/color]
[color=#0000CC]}[/color]
[color=#0000FF]if[/color][color=#0000CC]([/color]0 [color=#0000CC]![/color][color=#0000CC]=[/color] [color=#FF0000]fseek[/color][color=#0000CC]([/color]stream[color=#0000CC],[/color] 0[color=#0000CC],[/color] SEEK_CUR[color=#0000CC])[/color][color=#0000CC])[/color]
[color=#0000CC]{[/color]
[color=#FF0000]printf[/color][color=#0000CC]([/color] [color=#FF00FF]"Error! fseek != 0 /n"[/color] [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000FF]goto[/color] MAIN_GT1[color=#0000CC];[/color]
[color=#0000CC]}[/color]
[color=#0000CC]}[/color]
MAIN_GT1[color=#0000CC]:[/color]
[color=#FF0000]fclose[/color][color=#0000CC]([/color] stream [color=#0000CC])[/color][color=#0000CC];[/color]
[color=#0000CC]}[/color][/color][/font][/td][/tr][/table]
[[i] 本帖最后由 tgbvc 于 2008-2-20 16:49 编辑 [/i]]
tgbvc
TNND,害老子好苦!还指望CU能帮一下,嗨,令人失望。。。。。。。。。。。。。
[[i] 本帖最后由 tgbvc 于 2008-2-20 16:53 编辑 [/i]]
tgbvc
[quote]原帖由 [i]思一克[/i] 于 2008-2-20 16:57 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7983506&ptid=1054838][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
哪里的BUG,说清楚,别人看要花时间的 [/quote]
if(0 != fseek(stream, -1, SEEK_CUR))
{
printf( "Error! fseek != 0 /n" );
goto MAIN_GT1;
}
ch++;
if(1 != fwrite(&ch, 1, 1, stream))
{
printf( "Error! fwrite != 0 /n" );
goto MAIN_GT1;
}
if(0 != fseek(stream, 0, SEEK_CUR)) // 这样文件指针才能复位,
{
printf( "Error! fseek != 0 /n" );
goto MAIN_GT1;
}
flw2
在fread和fwrite之间需要fseek(stream,0,SEEK_SET);
tgbvc
[quote]原帖由 [i]flw2[/i] 于 2008-2-20 17:08 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7983587&ptid=1054838][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
在fread和fwrite之间需要fseek(stream,0,SEEK_SET); [/quote]
那不又文件头去了,怎么能顺序读,你还不明白题意吧。
flw2
[quote]原帖由 [i]tgbvc[/i] 于 2008-2-20 17:10 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7983602&ptid=1054838][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
那不又文件头去了,怎么能顺序读,你还不明白题意吧。 [/quote]
man fseek
flw2
循环之所以不停,是因为read write的缓冲可能是不同的,或者文件当前位置有两个,一个读写
能否把FILE的定义找出来?
tgbvc
[quote]原帖由 [i]flw2[/i] 于 2008-2-20 17:20 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7983686&ptid=1054838][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
循环之所以不停,是因为read write的缓冲可能是不同的,或者文件当前位置有两个,一个读写
能否把FILE的定义找出来? [/quote]
猜测也得靠谱。
flw2
[quote]原帖由 [i]tgbvc[/i] 于 2008-2-20 17:27 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7983751&ptid=1054838][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
猜测也得靠谱。 [/quote]
猜测要大胆,呵呵
你的循环不退出,就是因为永远没有超过当前文件结尾,所以我那么猜测
至少完全不能说是fseek的问题
fwrite和fread之间没有fseek(或等价的)行为是未定义的
错误的代码肯定不能证明有bug,尽管它可能真有bug
cjaizss
无论如何,标准I/O的输入输出之间要刷新流,这是C语言标准的规定。
Edengundam
代码...看起来很难受, 不过还是坚持下来....
你vc调试, 看stream里面, 有个ptr和base. 两个buffer
[[i] 本帖最后由 Edengundam 于 2008-2-20 18:01 编辑 [/i]]
flw2
简单的看了一下,linux下的stdio FILE是有两个指针,当fwrite时改变write指针,而不改变read指针,
但是buf指针后移,所以read种能得到,要下班了,在linux试试,估计结果一样
flw2
哦,才看见,你的正确的代码后面是有fseek
看一个FILE只有一个指针(当前位置)的fseek实现,不难想象有两个指针的fseek
int
fseek(FILE *stream, long int offset, int whence)
{
int adjust = 0;
long pos;
stream->_flags &= ~(_IOEOF | _IOERR);
/* Clear both the end of file and error flags */
if (io_testflag(stream, _IOREADING)) {
if (whence == SEEK_CUR
&& stream->_buf
&& !io_testflag(stream,_IONBF))
adjust = stream->_count;
stream->_count = 0;
} else if (io_testflag(stream,_IOWRITING)) {
fflush(stream);
} else /* neither reading nor writing. The buffer must be empty */
/* EMPTY */ ;
pos = _lseek(fileno(stream), offset - adjust, whence);
if (io_testflag(stream, _IOREAD) && io_testflag(stream, _IOWRITE))
stream->_flags &= ~(_IOREADING | _IOWRITING);
stream->_ptr = stream->_buf;
return ((pos == -1) ? -1 : 0);
}
ivhb
[quote]原帖由 [i]flw2[/i] 于 2008-2-20 17:08 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7983587&ptid=1054838][img]http://bbs.chinaunix.net/images/common/back.gif[/img][/url]
在fread和fwrite之间需要fseek(stream,0,SEEK_SET); [/quote]
呵呵,栽在这个上面人估计不会少。
醉卧水云间
;P ;P 乐死了, MS的fwrite都多少年了,还怀疑有BUG.
mailt
回复 #1 tgbvc 的帖子
这个...根据多年的经验总结,在下结论怀疑别人的BUG,尤其是成熟的开发库平台的BUG之前,最好还是自己先多试验一下,看看是否自己对某些东西的理解有偏差...