C++之文件輸入/輸出流類解讀
文件輸入/輸出流類
C++ 提供以下類來執(zhí)行文件的字符輸出和輸入:
ofstream
:寫入文件的流類ifstream
:從文件中讀取的流類fstream
:流類以讀取和寫入文件。
表5: 文件讀寫模式
讀寫模式 | 意義 |
---|---|
ios::in | 打開輸入操作(ifstream的默認模式)。 |
ios::out | 打開以進行輸出操作(ofstream的默認模式)。 |
ios::binary | 以二進制模式打開。 |
ios::ate | 在文件末尾設置初始位置。 如果未設置此標志,則初始位置是文件的開頭。 |
ios::app | 所有輸出操作都在文件末尾執(zhí)行,將內(nèi)容附加到文件的當前內(nèi)容。 |
ios::trunc | 如果打開文件以進行輸出操作并且它已經(jīng)存在,則刪除其先前的內(nèi)容并用新的內(nèi)容替換。 |
表6:ios_base 標識的組合意義
ios_base 標識 | 意義 | C模式 |
---|---|---|
in | 讀取 (文件必須存在) | “r” |
out | 清空之后改寫 (有必要才產(chǎn)生) | “w” |
out | trunc | 清空之后改寫 (有必要才產(chǎn)生) | “w” |
out | app | 添加 (有必要才產(chǎn)生) | “a” |
in | out | 讀和寫: 最初位置在起始點 (文件必須存在) | “r + ” |
in | out | trunc | 先清空, 再讀寫 (有必要才產(chǎn)生) | “w+” |
ofstream:寫入文件的流類
例8:輸出文本文件
#include <iostream> #include <iomanip> #include <vector> #include <string> #include <fstream> int main() { std::vector<std::string> fruit{ "火龍果","梨" }; std::vector<double> price{ 3.02,4.51 }; //使用輸出至顯示器 std::cout << "水果名 單價\n" << std::setiosflags(std::ios::left); for (int i = 0; i < 2; ++i) { std::cout << std::setw(8) << fruit[i]; std::cout << std::setw(6) << price[i]; std::cout << std::endl; } // 使用文件輸出流類ofstream的文件對象fout將數(shù)據(jù)輸出到文本文件price.txt std::ofstream fout; //文件輸出流類ofstream對象fout需要程序員自己定義 fout.open("price.txt",std::ios::out);//打開文件price.txt,如文件不存在則創(chuàng)建新文件 fout << "水果名 單價\n" << std::setiosflags(std::ios::left); for (int i = 0; i < 2; ++i) { fout << std::setw(8) << fruit[i]; fout << " "; fout << std::setw(6) << price[i]; fout << std::endl; } fout.close(); //關閉所打開的文件price.txt return 0; }
結果:
水果名 單價
火龍果 3.02
梨 4.51
例9:輸出二進制文件
#include <iostream> #include <iomanip> #include <string.h> #include <fstream> int main() { char *fruit[] = { "火龍果","梨" }; double price[] = { 3.02,4.51 }; char str[7]; //使用文件對象fout將數(shù)據(jù)輸出到二進制文件price.dat std::ofstream fout; //文件輸出流類ofstream對象fout需要程序員自己定義 fout.open("price.dat",std::ios::out|std::ios::binary);//以二進制模式打開文件price.dat,如文件不存在則創(chuàng)建新文件 for (int i = 0; i < 2; ++i) { strcpy(str,fruit[i]); fout.write(str,sizeof(str));//輸出水果名 fout.write((char*)(&price[i]),sizeof(double));//輸出價格 } fout.close(); //關閉所打開的文件price.dat return 0; }
ifstream:從文件中讀取的流類
例10:輸入文本文件
#include <iostream> #include <fstream> int main() { char fruit[20]; double price; std::ifstream fin; //使用文件輸入流類ifstream的文件對象fin從文本文件price.txt中輸入數(shù)據(jù) fin.open("price.txt"); //打開文本文件 if(fin.is_open()==false) //檢查打開文件是否成功 std::cout<<"打開文件price.txt失敗"<<std::endl; else { fin.getline(fruit,19); //讀出標題行 std::cout<<fruit<<std::endl; //顯示所讀出的標題行,顯示結果:水果名稱單價 for(int i=0;i<2;++i) { fin>>fruit>>price; //從文件price.txt中讀取水果名稱和單價 std::cout<<fruit<<","<<price<<std::endl; //顯示水果名稱和單價,驗證輸入結果 } fin.close(); //關閉所打開的文件price.txt } return 0; }
結果:
水果名 單價
火龍果,3.02
梨,4.51
例11:輸入二進制文件
#include <iostream> #include <iomanip> #include <fstream> int main() { char name[20]; double num; std::ifstream fin; fin.open("price.dat",std::ios::in |std::ios::binary); for (int i = 0; i < 2; ++i) { fin.read(name,7); fin.read((char*)(&num),8); std::cout<<name<<" "<<num<<std::endl; } fin.close(); //關閉所打開的文件price.dat return 0; }
結果:
火龍果 3.02
梨 4.51
表7:檢查流的特定狀態(tài)
成員函數(shù) | 意義 |
---|---|
good | 檢查是否沒有發(fā)生錯誤, |
eof | 檢查是否到達了文件末尾 |
fail | 檢查是否發(fā)生了可恢復的錯誤 |
bad | 檢查是否已發(fā)生不可恢復的錯誤 |
例12:檢查輸入文件狀態(tài)
#include <iostream> #include <fstream> int main() { char ch; std::ifstream fin; //使用文件輸入流類ifstream的文件對象fin從文本文件price.txt中輸入數(shù)據(jù) fin.open("price.txt"); //打開文本文件 while(true) { fin.get(ch); //從文件price.txt中每次讀取一個字符 //eof的返回值:true-文件已結束,false-文件未結束 //good的返回值:true-文件正常,false-文件已損壞 if(fin.eof()==true||fin.good()==false) break; //結束文件輸入 std::cout <<ch; //顯示所讀出的字符ch } fin.close(); //關閉所打開的文件price.txt return 0; }
結果:
水果名 單價
火龍果 3.02
梨 4.51
fstream:流類以讀取和寫入文件
表 8: 文件定位標志
模式標志 | 描述 |
---|---|
ios::beg | 從文件頭開始計算偏移量 |
ios::end | 從文件末尾開始計算偏移量 |
ios::cur | 從當前位置開始計算偏移量 |
隨機讀寫文件
打開文件后,文件對象與外存文件建立起關聯(lián)關系。此時,文件對象內(nèi)部將保存當前讀寫數(shù)據(jù)的位置信息。該位置信息保存在被稱作文件指針的數(shù)據(jù)成員中。
文件輸入流對象包含一個讀文件指針,文件輸出流對象包含一個寫文件指針,而文件輸入/輸出流對象則分別包含一個讀文件指針和一個寫文件指針。
通常情況下,打開文件后文件對象的讀/寫指針都定位于文件頭的位置。
每執(zhí)行一次讀/寫操作,讀/寫指針將自動后移,移到下一次讀/寫數(shù)據(jù)的位置。這就是文件的順序讀/寫。
可以調(diào)用函數(shù)成員seekg和tellg來移動或讀取讀文件指針的位置,調(diào)用函數(shù)成員seekp知和tellp來移動或讀取寫文件指針的位置。
程序員通過移動讀/寫指針,可實現(xiàn)對文件的隨機讀寫。
這4個與文件指針相關函數(shù)的原型如下:
文件指針相關函數(shù) | 描述 |
---|---|
istream& seekg(long bytes,ios::seek dir origin ) | 移動讀文件指針 |
long tellg() | 返回當前讀文件指針的位置 |
ostream& seekp(long bytes,ios::seek_dir origin ) | 移動寫文件指針 |
long tellp() | 返回當前寫文件指針的位置 |
例13:隨機讀寫文件
#include <iostream> #include <fstream> int main() { char fruit[20]; double price; std::ifstream fin; fin.open("price.dat"); //打開二進制文件 if(fin.is_open()==false) //檢查打開文件是否成功 std::cout<<"打開文件price.dat失敗"<<std::endl; else { for(int i=0;i<2;++i) { fin.read(fruit,7); //std::cout << fin.tellg() << '\n'; fin.read((char*)&price,8); std::cout << fin.tellg() << '\n'; //當前讀文件指針的位置 std::cout<<fruit<<","<<price<<std::endl; //顯示水果名稱和單價,驗證輸入結果 } fin.seekg(-30L,std::ios::end);//從文件尾向前(即往回)移動兩行(一行有15個字節(jié)) fin.read(fruit,7); std::cout<<fruit<<std::endl; fin.seekg(8L,std::ios::cur);//當前位置開始向后移動7個字節(jié) fin.read(fruit,7); std::cout<<fruit<<std::endl; fin.close(); //關閉所打開的文件price.dat } return 0; }
結果:
15
火龍果,3.02
30
梨,4.51
火龍果
梨
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
C++中vector<vector<int>?>的基本使用方法
vector<vector<int>?>其實就是容器嵌套容器,外層容器的元素類型是vector<int>,下面這篇文章主要給大家介紹了關于C++中vector<vector<int>?>的基本使用方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-07-07c語言中實現(xiàn)數(shù)組幾個數(shù)求次大值
這篇文章主要介紹了c語言中實現(xiàn)數(shù)組幾個數(shù)求次大值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12