程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 文件的輸入和輸出,文件輸入輸出

文件的輸入和輸出,文件輸入輸出

編輯:C++入門知識

文件的輸入和輸出,文件輸入輸出


文件的輸入和輸出

1.程序寫入文件 ,應遵循以下規則
(1)創建一個ofstream對象來管理輸出流
(2)將對象和輸出流關聯起來
(3)以使用cout的方式來使用該對象。
例如:

ofstream fout ;         //創建對象
fout.open(“jar.txt”) ; //關聯文件

注意:

 

  • Ofstream fout (“jar.txt”) ;//跟上面的兩條語句是等效的那麼關於第三點:使用cout的方式來使用該對象,比如:
  • fout << “ I love you !”;

原因:fout對象的類型是ofstream,他的基類是ostream,我們知道,派生類的對象是可以使用基類的方法的。
警告:
以這種方式來進行文件的輸出時,如果不存在這個文件,程序會創建並輸出,但是如果是已有文件。程序會清空並進行數據的輸出。(後面有關於如何打開已有文件,並保留其內容) 測試:測試成功 我們進入下一個內容:文件的讀取
(1)創建一個ifstream對象來管理輸入流
(2)將這個對象和特定的文件關聯
(3)以使用cin的方式使用該對象
例如:

Ifstream fin;            //創建對象  
in.open(“test.txt”);  //關聯文件
  • 上述兩條語句合並為一條是:ifstream fin(“test.txt”);//等價的

流狀態的檢查和is_open( )函數

C++流文件類從ios_base類那裡繼承了一個“流狀態成員”流狀態成員:存儲了指出流狀態的信息。比如說: 
一切順利,達到了文件尾,I/O操作失敗等等,通常來說,如果一切正常,那麼流狀態就會為0,其他的情況都是通過將特定位設置為1來記錄的。

我們先來了解:檢查試圖打開文件時是否成功打開:isopen()函數 if(!fin.isopen())//文件打開失敗 { ………… }

  • 這中方式可以檢測出一些微妙的問題:試圖以不合適的文件模式打開文件時失敗

文件模式

  • 文件模式描述的是:文件將如何被使用:讀,寫,追加等等。

問題:如何向文件中輸入數據,但保證文件原內容不被刪除


/創建對象,關聯文件
	//如果不想原有數據被刪除,必須注意第二參數的使用
	ofstream fout("qwe.txt",ios_base::out|ios_base::app);
	if(!fout.is_open())
		cout<<"文件打開失敗!";
	else
		fout<<"我叫茹鵬锟,來自西安建築科技大學";

說明:上述語句使用|運算符來合並模式,ios_base::out|ios_base::app意味著啟用模式out和app。
注意:在文件模式常量中:

這兩個的含義都是將文件指針指向打開的文件尾。

 

追加文件

補充:1.兩個函數 exit()
功能:關閉所有文件,終止正在進行的程序
頭文件:stdlib.h
2.EXIT_FAILURE

EXIT_FAILURE是C語言頭文件庫中定義的一個符號常量,
在vc++6.0下頭文件stdlib.h中定義如下:#define EXIT_FAILURE 1

EXIT_FAILURE 可以作為exit()的參數來使用,表示沒有成功地執行一個程序。
EXIT_SUCCESS 作為exit()的參數來使用,表示成功地執行一個程序。

我們來看一個程序實例

using namespace std;
//定義一個字符串指針,內容是"guest.txt"
const char* file = "guest.txt";
int main()
{
char ch;
//創建對象
ifstream fin;
//關聯對象
fin.open(file);
//檢查打開
if(fin.isopen())
{
	cout<<file<<"當前的數據是:"<<endl;
	while(fin.get(ch))
	  cout<<ch;
	fin.close();
}
//向文件中增加數據
ofstream fout(file,iosbase::out|ios_base::app);
if(!fout.isopen())
{
	cerr<<"can't open"<<file<<"file for output.\n";
	//終止程序,程序就結束了
	//不會再執行下面的內容了
	exit(1);
}
cout<<"輸入客戶的名字(如果讀到空行就停止):\n";
string name;
while(getline(cin,name) && name.size()>0)
{
	fout<<name<<endl;
}
fout.close();
//輸出結果的顯示
fin.clear();
fin.open(file);
if(fin.is
open())
{ cout<<file<<"文件的當前內容是:\n";
while(fin.get(ch))
cout<<ch;
fin.close();
} return 0; }

關於程序的幾點說明:
1.exit(1)會終止程序的進行,不再執行後面的代碼部分
2.第一次運行是無法打開文件的:

 

  • 因為新文件還沒有被創建

3.在追加文件後,顯示文本當前文本內容的時候,記得加入函數

  • fin.clear();

二進制文件:(略)


//這個是做什麼的
inline void eatline(){while(std::cin.get() != 'a') continue;}
//結構體類型
struct planet
{
	char name[20];
	double population;
	double g;
};
//一個指向char類型的字符串指針
const char* file="planets.dat";

int main()
{
	using namespace std;
	planet pl;
	//這個是干嘛的?
	cout<<<right; 創建對象="" ifstream="" fin;="" fin.open(file,ios_base::in|ios_base::binary);="" read讀取="" while(fin.read(="" (char*)&pl,="" sizeof="" pl))="" {="" 不清楚是什麼意思?會不會是輸出格式化="" cout=""><<setw(20)><<<": "
			<<setprecision(0)><<setw(12)><<<setprecision(2)><<setw(6)><<<endl; }="" 切斷聯系,關閉文件="" fin.close();="" 增加數據到新的文件中="" 創建對象="" ofstream="" fout(file,ios_base::out|ios_base::app|ios_base::binary);="" 判斷文件打開是否成功="" if(!fout.is_open())="" {="" cout=""><<<"file 打開失敗\n";
		//終止程序
		exit(1);
	}

	//數據讀入
	cout<<"請輸入行星的名字(輸入空行停止)\n";
	cin.get(pl.name,20);
	//判斷字符串第一個不是空
	while(pl.name[0] != '\0')
	{
		//調用了一個函數
		eatline();
		cout<<"請輸入行星的人口:\n";
		cin>>pl.population;
		cout<<"請輸入行星的重力加速度\n";
		cin>>pl.g;
		//為什麼又要調用這個函數
		eatline();
		//二進制文本輸入
		fout.write((char*)&pl, sizeof pl);
		cout<<"請輸入行星的名字(輸入空行表示停止):\n";
		cin.get(pl.name,20);
	}
	//切斷聯系:文件關閉
	fout.close();
	//二進制文件的顯示
	//估計只有我的電腦需要清空一下吧
	fin.clear();
	//關聯變量
	fin.open(file,ios_base::in|ios_base::binary);
	//判斷文件的打開
	if(fin.is_open())
	{
		cout<<<"文件當前的內容是:\n";
		while(fin.read((char*)&pl,sizeof pl))
		{
			cout<<setw(20)><<<": "
			<<setprecision(0)><<setw(12)><<<setprecision(2)><<setw(6)><<<endl; }="" 文件關閉="" fin.close();="" return="" 0;="">

程序的幾個說明:
(1)為什麼在返回值類型前面加上inline

在定義函數時,在返回值類型前加上inline表示把這個函數定義為內聯函數。
此類函數在編程過程中將在調用處將函數展開(就像處理#define宏一樣),
從而避免像普通函數一樣去調用,以節省程序執行開銷,提高運行效率。
  • 重點:節省可程序的開銷,提高了運行效率(不用去調用了)
    (2)inline void eatline(){while(std::cin.get() != 'a') continue;}這個內聯函數有什麼作用
其實`\n`比較不好理解,我們可以換一個字符`a`那麼在程序運行時我們就會發現,
只有當這個函數檢測到字符a,他才會跳出這個內聯函數的循環,這個內聯函數的作用說白了,就是為了
檢測設定的字符
  • 還有一點問題:為什麼 去掉之後,就不能多次輸入數據了
關於這一點書中給了明確的解釋:
這條內聯函數會導致程序讀取並丟棄包括換行符的內容,在他之後是cin.get(pl.name,20);
如果保留了換行符,那麼這條語句就會將換行符做空行讀取,從而終止操作

(3)關於語句cout<<fixed<<right;的意思是什麼? 右對齊和定點選項
c++在頭文件iomanip中提供了一些控制符,十分的方便,其實,最長用的也就是下面這三個  

  • setprecision() 設置精度
  • setfill()填充字符
  • setw()字段寬度

他們三個參數的情況說明: setprecision()控制符接受一個控制精度的整型參數,setfill()控制符接受一個指向指定的char類型的參數,setw()控制符接受一個指定字段寬度的整型參數。

  • 因為都是控制符,所以可以用cout語句鏈接起來
  • 在程序運行中發現:如果不編寫填充,它默認填充空白

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved