C++之文件輸入/輸出流類解讀
文件輸入/輸出流類
C++ 提供以下類來(lái)執(zhí)行文件的字符輸出和輸入:
ofstream:寫入文件的流類ifstream:從文件中讀取的流類fstream:流類以讀取和寫入文件。
表5: 文件讀寫模式
| 讀寫模式 | 意義 |
|---|---|
| ios::in | 打開輸入操作(ifstream的默認(rèn)模式)。 |
| ios::out | 打開以進(jìn)行輸出操作(ofstream的默認(rèn)模式)。 |
| ios::binary | 以二進(jìn)制模式打開。 |
| ios::ate | 在文件末尾設(shè)置初始位置。 如果未設(shè)置此標(biāo)志,則初始位置是文件的開頭。 |
| ios::app | 所有輸出操作都在文件末尾執(zhí)行,將內(nèi)容附加到文件的當(dāng)前內(nèi)容。 |
| ios::trunc | 如果打開文件以進(jìn)行輸出操作并且它已經(jīng)存在,則刪除其先前的內(nèi)容并用新的內(nèi)容替換。 |
表6:ios_base 標(biāo)識(shí)的組合意義
| ios_base 標(biāo)識(shí) | 意義 | C模式 |
|---|---|---|
| in | 讀取 (文件必須存在) | “r” |
| out | 清空之后改寫 (有必要才產(chǎn)生) | “w” |
| out | trunc | 清空之后改寫 (有必要才產(chǎn)生) | “w” |
| out | app | 添加 (有必要才產(chǎn)生) | “a” |
| in | out | 讀和寫: 最初位置在起始點(diǎn) (文件必須存在) | “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 << "水果名 單價(jià)\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的文件對(duì)象fout將數(shù)據(jù)輸出到文本文件price.txt
std::ofstream fout; //文件輸出流類ofstream對(duì)象fout需要程序員自己定義
fout.open("price.txt",std::ios::out);//打開文件price.txt,如文件不存在則創(chuàng)建新文件
fout << "水果名 單價(jià)\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(); //關(guān)閉所打開的文件price.txt
return 0;
}結(jié)果:
水果名 單價(jià)
火龍果 3.02
梨 4.51
例9:輸出二進(jìn)制文件
#include <iostream>
#include <iomanip>
#include <string.h>
#include <fstream>
int main()
{
char *fruit[] = { "火龍果","梨" };
double price[] = { 3.02,4.51 };
char str[7];
//使用文件對(duì)象fout將數(shù)據(jù)輸出到二進(jìn)制文件price.dat
std::ofstream fout; //文件輸出流類ofstream對(duì)象fout需要程序員自己定義
fout.open("price.dat",std::ios::out|std::ios::binary);//以二進(jìn)制模式打開文件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));//輸出價(jià)格
}
fout.close(); //關(guān)閉所打開的文件price.dat
return 0;
}ifstream:從文件中讀取的流類
例10:輸入文本文件
#include <iostream>
#include <fstream>
int main()
{
char fruit[20];
double price;
std::ifstream fin; //使用文件輸入流類ifstream的文件對(duì)象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); //讀出標(biāo)題行
std::cout<<fruit<<std::endl; //顯示所讀出的標(biāo)題行,顯示結(jié)果:水果名稱單價(jià)
for(int i=0;i<2;++i)
{
fin>>fruit>>price; //從文件price.txt中讀取水果名稱和單價(jià)
std::cout<<fruit<<","<<price<<std::endl; //顯示水果名稱和單價(jià),驗(yàn)證輸入結(jié)果
}
fin.close(); //關(guān)閉所打開的文件price.txt
}
return 0;
}結(jié)果:
水果名 單價(jià)
火龍果,3.02
梨,4.51
例11:輸入二進(jìn)制文件
#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(); //關(guān)閉所打開的文件price.dat
return 0;
}結(jié)果:
火龍果 3.02
梨 4.51
表7:檢查流的特定狀態(tài)
| 成員函數(shù) | 意義 |
|---|---|
| good | 檢查是否沒有發(fā)生錯(cuò)誤, |
| eof | 檢查是否到達(dá)了文件末尾 |
| fail | 檢查是否發(fā)生了可恢復(fù)的錯(cuò)誤 |
| bad | 檢查是否已發(fā)生不可恢復(fù)的錯(cuò)誤 |
例12:檢查輸入文件狀態(tài)
#include <iostream>
#include <fstream>
int main()
{
char ch;
std::ifstream fin; //使用文件輸入流類ifstream的文件對(duì)象fin從文本文件price.txt中輸入數(shù)據(jù)
fin.open("price.txt"); //打開文本文件
while(true)
{
fin.get(ch); //從文件price.txt中每次讀取一個(gè)字符
//eof的返回值:true-文件已結(jié)束,false-文件未結(jié)束
//good的返回值:true-文件正常,false-文件已損壞
if(fin.eof()==true||fin.good()==false)
break; //結(jié)束文件輸入
std::cout <<ch; //顯示所讀出的字符ch
}
fin.close(); //關(guān)閉所打開的文件price.txt
return 0;
}結(jié)果:
水果名 單價(jià)
火龍果 3.02
梨 4.51
fstream:流類以讀取和寫入文件
表 8: 文件定位標(biāo)志
| 模式標(biāo)志 | 描述 |
|---|---|
| ios::beg | 從文件頭開始計(jì)算偏移量 |
| ios::end | 從文件末尾開始計(jì)算偏移量 |
| ios::cur | 從當(dāng)前位置開始計(jì)算偏移量 |
隨機(jī)讀寫文件
打開文件后,文件對(duì)象與外存文件建立起關(guān)聯(lián)關(guān)系。此時(shí),文件對(duì)象內(nèi)部將保存當(dāng)前讀寫數(shù)據(jù)的位置信息。該位置信息保存在被稱作文件指針的數(shù)據(jù)成員中。
文件輸入流對(duì)象包含一個(gè)讀文件指針,文件輸出流對(duì)象包含一個(gè)寫文件指針,而文件輸入/輸出流對(duì)象則分別包含一個(gè)讀文件指針和一個(gè)寫文件指針。
通常情況下,打開文件后文件對(duì)象的讀/寫指針都定位于文件頭的位置。
每執(zhí)行一次讀/寫操作,讀/寫指針將自動(dòng)后移,移到下一次讀/寫數(shù)據(jù)的位置。這就是文件的順序讀/寫。
可以調(diào)用函數(shù)成員seekg和tellg來(lái)移動(dòng)或讀取讀文件指針的位置,調(diào)用函數(shù)成員seekp知和tellp來(lái)移動(dòng)或讀取寫文件指針的位置。
程序員通過移動(dòng)讀/寫指針,可實(shí)現(xiàn)對(duì)文件的隨機(jī)讀寫。
這4個(gè)與文件指針相關(guān)函數(shù)的原型如下:
| 文件指針相關(guān)函數(shù) | 描述 |
|---|---|
| istream& seekg(long bytes,ios::seek dir origin ) | 移動(dòng)讀文件指針 |
| long tellg() | 返回當(dāng)前讀文件指針的位置 |
| ostream& seekp(long bytes,ios::seek_dir origin ) | 移動(dòng)寫文件指針 |
| long tellp() | 返回當(dāng)前寫文件指針的位置 |
例13:隨機(jī)讀寫文件
#include <iostream>
#include <fstream>
int main()
{
char fruit[20];
double price;
std::ifstream fin;
fin.open("price.dat"); //打開二進(jìn)制文件
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'; //當(dāng)前讀文件指針的位置
std::cout<<fruit<<","<<price<<std::endl; //顯示水果名稱和單價(jià),驗(yàn)證輸入結(jié)果
}
fin.seekg(-30L,std::ios::end);//從文件尾向前(即往回)移動(dòng)兩行(一行有15個(gè)字節(jié))
fin.read(fruit,7);
std::cout<<fruit<<std::endl;
fin.seekg(8L,std::ios::cur);//當(dāng)前位置開始向后移動(dòng)7個(gè)字節(jié)
fin.read(fruit,7);
std::cout<<fruit<<std::endl;
fin.close(); //關(guān)閉所打開的文件price.dat
}
return 0;
}結(jié)果:
15
火龍果,3.02
30
梨,4.51
火龍果
梨
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C++中實(shí)現(xiàn)線程安全和延遲執(zhí)行詳解
這篇文章主要為大家詳細(xì)介紹了C++中實(shí)現(xiàn)線程安全和延遲執(zhí)行的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以了解下2024-01-01
深入探討C語(yǔ)言中局部變量與全局變量在內(nèi)存中的存放位置
本篇文章是對(duì)在C語(yǔ)言中局部變量與全局變量在內(nèi)存中的存放位置進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲
這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
C語(yǔ)言控制臺(tái)實(shí)現(xiàn)打飛機(jī)小游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言控制臺(tái)實(shí)現(xiàn)打飛機(jī)小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
OpenCV+Qt實(shí)現(xiàn)圖像處理操作工具的示例代碼
這篇文章主要介紹了利用OpenCV+Qt實(shí)現(xiàn)圖像處理操作工具,可以實(shí)現(xiàn)雪花屏、高斯模糊、中值濾波、毛玻璃等操作,感興趣的可以了解一下2022-08-08
C語(yǔ)言實(shí)現(xiàn)可增容動(dòng)態(tài)通訊錄詳細(xì)過程
這篇文章主要為大家介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易通訊錄的完整流程,此通訊錄還可以增容,并且每個(gè)環(huán)節(jié)都有完整代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-05-05
Qt?加載?libjpeg?庫(kù)出現(xiàn)“長(zhǎng)跳轉(zhuǎn)已經(jīng)運(yùn)行”錯(cuò)誤問題解決
這篇文章主要介紹了Qt?加載?libjpeg?庫(kù)出現(xiàn)“長(zhǎng)跳轉(zhuǎn)已經(jīng)運(yùn)行”錯(cuò)誤,本文給大家分享完美解決方案,需要的朋友可以參考下2023-04-04
C++實(shí)現(xiàn)漢諾塔算法經(jīng)典實(shí)例
這篇文章主要介紹了C++實(shí)現(xiàn)漢諾塔算法經(jīng)典實(shí)例,代碼簡(jiǎn)潔高效,對(duì)于學(xué)習(xí)算法的朋友有一定的借鑒價(jià)值,需要的朋友可以參考下2014-07-07

