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)能確保結果符合預期。