一个有关fstream类的bug
2006-08-10 19:10
260 查看
一个有关fstream类的bug
近日写程序需要读出文件,对读出的内容作些修改,再写回到文件中。
突然发现一个莫名其妙的问题,写回去的时候居然在文件末尾增加了几个字
符。感到很不可思议。具体代码如下:
fstream infile;
infile.open("c://test.txt", ios::in);
infile.seekp(0, ios::end);
int iFileLen = infile.tellp();
cout << "File len:" << iFileLen << endl;
char * pBuff = new char[iFileLen + 1];
memset(pBuff, 0, iFileLen + 1);
infile.seekp(0, ios::beg);
infile.read(pBuff, iFileLen);
infile.close();
fstream outfile;
outfile.open("c://test1.txt", ios::out|ios::trunc);
outfile.write(pBuff, iFileLen);
outfile.close();
delete[] pBuff;
在文件test.txt中输入一个字符'.'以及一个回车键,用UE打开,发现该
文件有三个字符,十六进制表示如下:2E 0D 0A。而在屏幕中打印出来的文件
大小也是3。可是文件test1.txt文件大小却变成了4,其十六进制表示变成了:
2E 0D 0A 00。莫名其妙的多了一个字节。可是明明写入的字节数应该是3啊。
怎么写到文件中去却变成了4了呢?很奇怪的问题。难道是write的问题?于是
我换了一种写文件方式,改成下面的方式:
for(int i = 0; i < iFileLen; i++)
outfile << pBuff[i];
但是结果仍然同上,仍然多了一个字节。于是感到可能是fstream这个类的问
题,以前也发觉该类在使用seekp时会出错。于是改成用c语言的文件流读写
操作,具体实现如下:
FILE * f = fopen("c://test.txt", "r");
fseek(f, 0, SEEK_END);
int len = ftell(f);
printf("the file len: %d /n", len);
fseek(f, 0, SEEK_SET);
char * p = new char[len + 1];
memset(p, 0x00, len + 1);
fread(p, sizeof(char), len, f);
fclose(f);
f = fopen("c://test1.txt", "w");
fwrite(p, sizeof(char), len, f);
fclose(f);
delete[] p;
可惜结果仍然没变。这就比较奇怪了。怎么会出现这种情况呢?明明文件
大小为3,为何写到另外一个文件中去却变成了4呢?于是在程序读出test.txt
文件内容的下一行添加了一条语句:
for(int i = 0; i < len; i++)
cout << (int)p[i];
结果在屏幕上显示的居然是这个结果:46 10 0。居然没有把0A输出。而是
输出了0。我突然想到fread返回的结果是真正读到数据p中的长度,于是我又改
变了一下上面的程序,将fread的结果打印出来:
cout << fread(p, sizeof(char), len, f) << endl;
结果果然是2,而不是想当然的3。原来在window下,回车换行的两个字符读到
一个数组中去时,只会在数组中保存一个字符:0D。但是用feek来计算文件长
度时返回的却是文件的实际大小,而不是真正读入到数组中的值。
于是,采用fstream类来写入的时候,文件中每多一个回车换行,实际用
read函数读到字符数组中的个数就减少一个。而前面我仍然用文件长度来将读
到字符数组中的内容写到某个文件中去时,显然会多写入一些字符。而这些多
写入的字符值由于一开始用memset置为0,所以最后在test1.txt文件中就多了
几个值为0的字符。
显然,用fstream类是无法解决这个问题的。因为它没法返回真正读到字符
数组中的个数。所以当写回文件时会多写入字符。除非在读文件时判断有多少
回车换行符,从而在总文件大小中减去这部分值,才是真正读到字符数组中的
值。所以,解决这个问题只能使用fread函数,因为该函数提供了一个返回参数
来告知真正读到字符数组中的字符个数(或者使用window提供的API:ReadFile)
该函数也同样提供了一个返回参数。
因此,在window下读出一个文件时,遇到回车换行两个字符,只会读入一个
字符:0A。以后在处理时,只能判断是否是0A来判断换行,而不能判断0d来判断
是否换行。而读出文件的真正大小需要用fread函数来得知。
近日写程序需要读出文件,对读出的内容作些修改,再写回到文件中。
突然发现一个莫名其妙的问题,写回去的时候居然在文件末尾增加了几个字
符。感到很不可思议。具体代码如下:
fstream infile;
infile.open("c://test.txt", ios::in);
infile.seekp(0, ios::end);
int iFileLen = infile.tellp();
cout << "File len:" << iFileLen << endl;
char * pBuff = new char[iFileLen + 1];
memset(pBuff, 0, iFileLen + 1);
infile.seekp(0, ios::beg);
infile.read(pBuff, iFileLen);
infile.close();
fstream outfile;
outfile.open("c://test1.txt", ios::out|ios::trunc);
outfile.write(pBuff, iFileLen);
outfile.close();
delete[] pBuff;
在文件test.txt中输入一个字符'.'以及一个回车键,用UE打开,发现该
文件有三个字符,十六进制表示如下:2E 0D 0A。而在屏幕中打印出来的文件
大小也是3。可是文件test1.txt文件大小却变成了4,其十六进制表示变成了:
2E 0D 0A 00。莫名其妙的多了一个字节。可是明明写入的字节数应该是3啊。
怎么写到文件中去却变成了4了呢?很奇怪的问题。难道是write的问题?于是
我换了一种写文件方式,改成下面的方式:
for(int i = 0; i < iFileLen; i++)
outfile << pBuff[i];
但是结果仍然同上,仍然多了一个字节。于是感到可能是fstream这个类的问
题,以前也发觉该类在使用seekp时会出错。于是改成用c语言的文件流读写
操作,具体实现如下:
FILE * f = fopen("c://test.txt", "r");
fseek(f, 0, SEEK_END);
int len = ftell(f);
printf("the file len: %d /n", len);
fseek(f, 0, SEEK_SET);
char * p = new char[len + 1];
memset(p, 0x00, len + 1);
fread(p, sizeof(char), len, f);
fclose(f);
f = fopen("c://test1.txt", "w");
fwrite(p, sizeof(char), len, f);
fclose(f);
delete[] p;
可惜结果仍然没变。这就比较奇怪了。怎么会出现这种情况呢?明明文件
大小为3,为何写到另外一个文件中去却变成了4呢?于是在程序读出test.txt
文件内容的下一行添加了一条语句:
for(int i = 0; i < len; i++)
cout << (int)p[i];
结果在屏幕上显示的居然是这个结果:46 10 0。居然没有把0A输出。而是
输出了0。我突然想到fread返回的结果是真正读到数据p中的长度,于是我又改
变了一下上面的程序,将fread的结果打印出来:
cout << fread(p, sizeof(char), len, f) << endl;
结果果然是2,而不是想当然的3。原来在window下,回车换行的两个字符读到
一个数组中去时,只会在数组中保存一个字符:0D。但是用feek来计算文件长
度时返回的却是文件的实际大小,而不是真正读入到数组中的值。
于是,采用fstream类来写入的时候,文件中每多一个回车换行,实际用
read函数读到字符数组中的个数就减少一个。而前面我仍然用文件长度来将读
到字符数组中的内容写到某个文件中去时,显然会多写入一些字符。而这些多
写入的字符值由于一开始用memset置为0,所以最后在test1.txt文件中就多了
几个值为0的字符。
显然,用fstream类是无法解决这个问题的。因为它没法返回真正读到字符
数组中的个数。所以当写回文件时会多写入字符。除非在读文件时判断有多少
回车换行符,从而在总文件大小中减去这部分值,才是真正读到字符数组中的
值。所以,解决这个问题只能使用fread函数,因为该函数提供了一个返回参数
来告知真正读到字符数组中的字符个数(或者使用window提供的API:ReadFile)
该函数也同样提供了一个返回参数。
因此,在window下读出一个文件时,遇到回车换行两个字符,只会读入一个
字符:0A。以后在处理时,只能判断是否是0A来判断换行,而不能判断0d来判断
是否换行。而读出文件的真正大小需要用fread函数来得知。
相关文章推荐
- 一个有关fstream类的bug
- 一个有关fstream类的bug
- 有关 IE 6 的一个 BUG
- 与MySQL的注释、Query_cache有关的一个bug
- 一个有关canvas的Bug
- AIX6.1/11.2.0.3在有关数据库SWAP一个BUG
- 一个有关sizeof的bug
- iOS 6中与中文键盘有关的一个BUG
- 与端口冲突有关的一个低概率bug的定位过程(这次不是360的错啊)---浅谈bind()函数返回失败
- 今天又发现IE的一个BUG!与Binary Behavior有关
- 与number_format函数有关的一个bug?
- MySQL的注释、Query_cache有关的一个bug
- 有关ArrayList增加Map引发的一个BUG
- 关于long_query_time的设置,可不可以说是mysql的一个小小bug呢
- NDK中使用pthread多线程中自己写的一个BUG
- 答读者问(22):一个在校学生有关持续学习的疑问及答复
- 关于c语言的一个小bug(c专家编程)
- 发现IDEA15.4相对引用的一个BUG
- luatinker 的一个计数 BUG
- 真高兴啊。。。。实际的为开源事业做了点点贡献:),很久前指出的一个lua stdlib的bug得到确认