A. 关于c++中流随机访问和文件读写问题
#include<string>
#include<iostream>
#include<sstream>
#include<fstream>
usingnamespacestd;
intmain(intargc,char*argv[])
{
fstreamfs("aa.txt",fstream::ate|fstream::in|fstream::out);//打开文件供读写,移到结尾
if(!fs) //打开文件出错
{
cerr<<"Unabletoopenfile!"<<endl;
returnEXIT_FAILURE;
}
autoend_mark=fs.tellg(); //定义文件结束标记,等于文件长度
cout<<"end_mark="<<end_mark<<endl;
fs.seekg(0,fstream::beg); //操作指针移到文件开始
intcnt=0;
stringline;
while(fs&&fs.tellg()!=end_mark&&getline(fs,line))
{
//cout<<"line="<<line<<endl;
cnt+=line.size()+1;
automark=fs.tellg();
cout<<"mark="<<mark<<endl;//保存并输出当前指针位置
fs.seekp(0,fstream::end); //操作指针移到文件结尾
fs<<cnt; //写入计数
if(mark!=end_mark)fs<<""; //文件未完,继续读
fs.seekg(mark); //操作指针移回上面保存的读取位置
}
cout<<"tellg()="<<fs.tellg()<<endl;//这时看看,位置到结尾了.
//fs.seekp(0,fstream::beg);
cout<<"注意这个输出:"<<line<<endl;//上面循环中getline(fs,line)已经读到最后一行了,
//注意看了,这是为什么原程序不会往文件结尾写入"****"的原因:
//在上面while循环操作中,操作指针已移到文件结尾,再调用seekg有可能出现无效!!
//必须先clear()或者再随便移一下指针位置,按http://www.cplusplus.com/reference/istream/istream/seekg/
//里面提到:
//C++99:,thefunctionfails(setsfailbitandreturns).
//C++11:,ifsetbeforethecall.
///网上大神也说:endoffile的时候,seek是无效的,必须先clear.
//所以,会出现问题中的星号写不进文件的情形.保险起见,下面改成:
fs.clear();//或者用下面这句,两句选一
//fs.seekg(0,fstream::beg); //动一动指针,移到文件开始
//不然,进不了下面判断中if部分.总之,这一部分挺乱的,C++98,C++11标准支持不同.
if(fs)//先判断文件还有没有打开
{
fs.seekp(0,fstream::end); //移到结尾.
fs<<cnt; //写入最后一行计数
fs<<"**** "; //原程序根本来不到这里.所以无法操作.现在可以操作了,写入.
cout<<"success!"<<endl;
}
else
{
cout<<"endoffile"<<endl;
}
fs.close();
//system("pause");
return0;
}
B. 在C语言中fseek()的功能
fseek()是重定位流(数据流/文件)上的文件内部位置指针。
注意:文件指针指向文件/流。位置指针指向文件内部的字节位置,随着文件的读取会移动,文件指针如果不重新赋值将不会改变或指向别的文件。
如果执行成功,stream将指向以fromwhere为基准,偏移offset(指针偏移量)个字节的位置,函数返回0。如果执行失败(比如offset取值大于等于2*1024*1024*1024,即long的正数范围2G),则不改变stream指向的位置,函数返回一个非0值。
(2)随机访问文件c程序扩展阅读:
注意事项
fseek函数的文件指针,应该为已经打开的文件。如果没有打开的文件,那么将会出现错误。 fseek函数也可以这样理解,相当于在文件当中定位。
这样在读取规律性存储文件时可以利用其OFFSET偏移量读取文件上任意的内容。
fseek函数一般用于二进制文件,也可以用于文本文件。用于文本文件操作时,需特别注意只有fseek(fp, 0, SEEK_SET) 和 fseek(fp, ftell(fp), SEEK_SET)能确保结果符合预期。