1. 簡單的文件I/O
寫入文件 :
讓程序寫入文件,其步驟大致為如下:
- 創建一個
ofstream
對象來管理輸入流; - 將該對象與特定的文件關聯起來;
- 用使用
cout
的方式使用該對象,唯一的區別是輸出將進入文件,而不是屏幕。
例子:
//需要包含頭文件fstream
ofstream fout; //#1
fout.open("a.txt");//#2 若a.txt不存在,則會新建一個,若存在,則會清空源文件內容
fout < < "hello"; //#3 將hello寫入a.txt中
【 注 :以默認模式打開文件(即上述方式)進行輸出將自動把文件的長度截短為零,這相當于刪除已有的內容。具體原因見本文第三節文件模式中的注】
讀取文件
讀取文件的要求與寫入文件相似:
- 創建一個
ifstream
對象來管理輸入流; - 將該對象與特定的文件關聯起來;
- 以使用
cin
的方式使用該對象。
例子:
//需要包含頭文件fstream
ifstream fin; //#1
fin.open("a.txt");//#2
char ch;
fin > > ch; //#3 讀取一個字符放入ch
【 注 :當輸入和輸出流對象過期(如程序終止)時,到文件的連接將自動關閉。另外,也可以使用close()
方法來顯式地關閉到文件的連接。關閉這樣的連接并不會刪除流,而只是斷開流到文件的連接。然而,流管理裝置仍被保留。】
流狀態檢查
C++文件流類從ios_base
類那里繼承了一個流狀態成員。檢查文件是否成功打開的常見方式如下:
ifstream fin;
fin.open(argv[file]);
if (fin.fail()){...} //判斷文件打開是否成功
if (!fin.good()){...} //判斷文件打開是否成功
if (!fin){...} //判斷文件打開是否成功
//is_open()能夠檢測到這種錯誤以及good()能夠檢測到的錯誤。然而,老式C++實現沒有is_open( )。
if (!fin.is_open()){...} //判斷文件打開是否成功
2. 命令行處理技術
文件處理程序通常使用命令行參數來指定文件。例如:
exc a.txt b.txt
exc
為程序可執行文件名,a.txt
和b.txt
為程序exc
執行過程中要使用到的文件。要實現上述功能,則程序的主函數應該寫為:
int main(int argc, char* argv[])
argc
為命令行中的參數個數,其中包括命令名本身。argv
變量為一個指針,它指向一個指向char的指針。這過于抽象,但可以將argv
看作一個指針數組,其中的指針指向命令行參數,argv[0]
是一個指針,指向存儲第一個命令行參數的字符串的第一個字符,依此類推。也就是說,argv[0]
是命令行中的第一個字符串,依此類推。因此上面的例子中:argc
為3,argv[0]
為exc
,argv[1]
為a.txt
,argv[2]
為b.txt
。
3. 文件模式
文件模式描述的是文件將被如何使用:讀、寫、追加等。將流與文件關聯時(無論是使用文件名初始化文件流對象,還是使用open()
方法),都可以提供指定文件模式的第二個參數:
ifstream fin("banjo", mode1); // mode1為文件模式
ofstream fout();
fout.open("harp", mode2); // mode2為文件模式
文件模式的常量有:
【 注 :ifstream``open()
方法和構造函數用ios_base::in
(打開文件以讀取)作為模式參數的默認值,而ofstream``open()
方法和構造函數用ios_base::out | ios_base::trunc
(打開文件,以讀取并截短文件,也就是說,其以前的內容將被刪除)作為默認值。位運算符OR(|
)用于將兩個位值合并成一個可用于設置兩個位的值。fstream
類不提供默認的模式值,因此在創建這種類的對象時,必須顯式地提供模式。】
如果要保留文件內容,并在文件尾添加(追加)新信息,則可以使用ios_base::app
模式:
ofstream fout("bagels", ios_base::out | ios_base::app);//使用|運算符來合并模式,啟用模式out和app
老式C++實現之間可能有一些差異。例如,有些實現允許省略前一例子中的ios_base::out
,有些則不允許。如果不使用默認模式,則最安全的方法是顯式地提供所有的模式元素。
要以二進制格式(而不是文本格式)存儲數據,可以使用ofstream
對象的write()
成員函數。該方法將內存中指定數目的字節復制到文件中。若從二進制文件讀取數據,可以使用ifstream
對象的read( )
成員函數。該方法從文件中內容復制到目標結構中。這兩者的對應的使用方法如下:
const int LIM = 20;
struct planet
{
char name[LIM]; // name of planet
double population; // its population
double g; // its acceleration of gravity
};
planet pl;
planet p2;
//寫入
//ofstream fout("planets.dat", ios_base:: out | ios_base::app);
//fout < < pl.name < < " " < < pl.population < < " " < < pl.g < < "n";
ofstream fout("planets.dat",
ios_base:: out | ios_base::app | ios_base::binary);
fout.write( (char *) &pl, sizeof(pl));
//讀取
ifstream fin("planets.dat", ios_base::in | ios_base::binary);
fin.read((char *) &p2, sizeof(p2));
4. 隨機存取
隨機存取指的是直接移動(不是依次移動)到文件的任何位置。要實現讀/寫的效果,需要同時使用in
模式和out
模式將得到讀/寫模式,要使用|
運算符來組合模式。因此,需要使用下面的語句:
fstream finout;//fstream類是從iostream類派生而來的,而后者基于istream和ostream兩個類,因此它繼承了它們的方法。它還繼承了兩個緩沖區,一個用于輸入,一個用于輸出,并能同步化這兩個緩沖區的處理。
finout.open(file, ios_base::in | ios_base::out | ios_base::binary);
接下來,需要一種在文件中移動的方式。fstream
類為此繼承了兩個方法:seekg()
和seekp()
,前者將輸入指針移到指定的文件位置,后者將輸出指針移到指定的文件位置(實際上,由于fstream
類使用緩沖區來存儲中間數據,因此指針指向的是緩沖區中的位置,而不是實際的文件)。也可以將seekg()
用于ifstream
對象,將seekp()
用于oftream
對象。
seekg()
和seekp()
的原型及使用方法如下:
//seekg()
istream & seekg(streamoff, ios_base::seekdir);//第一個原型定位到離第二個參數指定的文件位置特定距離(單位為字節)的位置;streamoff值被用來度量相對于文件特定位置的偏移量(單位為字節)。
istream & seekg(streampos);//第二個原型定位到離文件開頭特定距離(單位為字節)的位置。streampos對應的是距離(單位為字節)。
//seek_dir參數是ios_base類中定義的另一種整型,有3個可能的值:
//常量ios_base::beg指相對于文件開始處的偏移量;
//常量ios_base::cur指相對于當前位置的偏移量;
//常量ios_base::end指相對于文件尾的偏移量。
fin.seekg(30, ios_base::beg); //將讀取位置設置為從文件開頭開始的第31個字節(字節編號為30)
fin.seekg(-1, ios_base::cur); //將讀取位置設置為從當前位置后退1個字節
fin.seekg(0, ios_base::end); //將讀取位置設置為從文件尾0個字節的位置
fin.seekg(112); //第一個字節的編號為0。因此該語句將讀取位置設置為第112個字節,也就是文件中的第113個字節
//seekp()
ostream & seekp(streamoff offset,seek_dir origin);
ostream & seekp (streampos pos);
fout.seekp(30, ios_base::beg); //將寫入位置設置為從文件開頭開始的第31個字節(字節編號為30)
fout.seekp(-1, ios_base::cur); //將寫入位置設置為從當前位置后退1個字節
fout.seekp(0, ios_base::end); //將寫入位置設置為從文件尾0個字節的位置
fout.seekp(112); //第一個字節的編號為0。因此該語句將寫入位置設置為編號為112的字節,也就是文件中的第113個字節
【 注 :如果要檢查文件指針的當前位置,則對于輸入流,可以使用tellg()
方法,對于輸出流,可以使用tellp()
方法。它們都返回一個表示當前位置的streampos
值(以字節為單位,從文件開始處算起)。】
seekg()
和seekp()
函數提供對文件的隨機存取。這些類方法使得能夠將文件指針放置到相對于文件開頭、文件尾和當前位置的某個位置。tellg()
和tellp()
方法報告當前的文件位置。
-
處理器
+關注
關注
68文章
19460瀏覽量
231404 -
連接器
+關注
關注
98文章
14715瀏覽量
137413 -
緩沖器
+關注
關注
6文章
1974瀏覽量
45703 -
二進制
+關注
關注
2文章
801瀏覽量
41779
發布評論請先 登錄
相關推薦
什么是簡單電路?簡述簡單電路的計算步驟?
![什么是<b class='flag-5'>簡單</b>電路?簡述<b class='flag-5'>簡單</b>電路的計算<b class='flag-5'>步驟</b>?](https://file1.elecfans.com//web2/M00/A4/68/wKgZomUMNBOAac5_AABEqpIqinM374.jpg)
Allegro生成鉆孔文件的步驟
AD中關于Gerber文件的輸出
電腦卡怎么辦簡單步驟
DXP導出SMT坐標文件的簡述步驟詳細說明
![DXP導出SMT坐標<b class='flag-5'>文件</b>的簡述<b class='flag-5'>步驟</b>詳細說明](https://file.elecfans.com/web1/M00/AA/43/o4YBAF2oNkKAILcjAAgrkuonuA4464.png)
AltiumDesigner導出Gerber文件的步驟詳細教程說明
![AltiumDesigner導出Gerber<b class='flag-5'>文件</b>的<b class='flag-5'>步驟</b>詳細教程說明](https://file.elecfans.com/web1/M00/AF/43/pIYBAF3fMmmAP18hAAc3VzW_kEQ351.png)
VC++簡單的輸入輸出教程詳細說明
![VC++<b class='flag-5'>簡單</b>的<b class='flag-5'>輸入輸出</b>教程詳細說明](https://file.elecfans.com/web1/M00/B8/90/pIYBAF5zJ3GANHT7AAElptgitnE720.png)
評論