計算機概論:C/C++程式設計
|
第7章 檔案輸入/輸出 |
|
||||||||||||||||||||||||||||||||||||||||||
|
授課教師:陳慶瀚 WWW : http://www.miat.ee.isu.edu.tw/cpp E-mail : pierre@isu.edu.tw |
|
||||||||||||||||||||||||||||||||||||||||||
7.5輸入/輸出的格式化 格式化資料有幾個好處,首先資料排列整齊,易於閱覽分析和管理,其次格式化的資料也利於檔案讀取的方便性和效率。有三種方式可以對資料輸出進行格式化,第一種是使用ios物件的格式設定旗標;第二種是使用串流物件的成員函式來指定輸出資料的寬度、填充字元或小數點後面的輸出位數;第三種方式使用一種特殊的指令,稱為格式操作子(manipulator)。這三種格式化資料的方法不但適用在檔案輸入/輸出串流物件(即fstream, ifstream, ofstream等物件),也適用在所有的串流資料輸入/輸出串流物件(包含鍵盤輸入cin和螢幕輸出cout)。 設定ios物件的格式旗標 ios物件中,我們可以根據需要設定各種格式旗標,以下列出所有設定值的旗標名稱: skipws 當設定ios::
skipws,則輸出串流資料時空白字元(spaces, tabs, 和endl)會被忽略。 left 當設定ios:: left,輸出串流資料向左切齊。 當設定ios:: right,輸出串流資料向左切齊。 當設定ios:: internal,不同位數的數值會被補齊。 當設定ios::dec,
ios::oct, ios::hex,輸出資料將會分別以10進制、8進制和16進制來呈現。 showbase 當設定ios::
showbase,輸出資料將會顯示其數值的進位基底(base of value),16進位的數值F3就會顯示0xF3 showpoint 當設定ios::
showbase,輸出浮點數數值時,小數點後面的數元(digit) 不管是不是0,都會全部輸出。 uppercase 當設定ios::
uppercase,輸出浮點數數值時,會將數值中的英文字母轉為大寫,如2.5e-4變成2.5E-4。 showpos 當設定ios::
showpos,輸出正整數時,前面會加上'+'號,例如輸出123,顯示+123。 scientific 當設定ios::
scientific,數值將以科學記法輸出。例如123.23輸出時就會變成1.232300e+02。 fixed 當設定ios::
scientific,數值將以科學記法輸出。例如123.23輸出時就會變成1.232300e+02。 unitbuf 當設定ios::
unitbuf,則在每一次輸出動作之後,C++的I/O系統就被更新一次。 了解上述格式化的旗標之後,接下來我們要看看如何使用它們。對於任何輸出串流物件─包括cout和ofstream,我們都可以使用串流物件的成員函式setf(
)來設定其格式,其語法為: 串流物件名稱.setf(ios::格式化旗標); 例如 cout.setf(ios:: scientific); 我們還可以用邏輯OR(|)來設定設定兩種以上的旗標,例如: cout.setf(ios::
scientific|
ios:: showpos); 便可以同時設定兩種格式化旗標:ios::
scientific和ios:: showpos。或著我們也可以將其分解為兩行,其功能是相同的: cout.setf(ios::
scientific); cout.setf(ios::
showpos); /*----------------------------------------------------*/ // 範例程式7-11 // 設定格式化旗標 // 陳慶瀚,2001 /*----------------------------------------------------*/ #include <iostream.h> void main() { int x=123; float y=123.23;
cout.setf(ios::showpos);
cout.setf(ios::scientific); cout << x
<< " " << y << " "; } 這個程式的執行結果如下: +123 +1.232300e+02 課堂練習 請將範例程式7-11改成檔案輸出。 除了設定格式旗標的函式,我們還可以清除已設定的格式旗標。對於任何輸出串流物件─包括cout和ofstream,我們都可以使用串流物件的成員函式unsetf( )來清除其原有的格式旗標,其語法為: 串流物件名稱.unsetf(ios::格式化旗標); 例如 cout.unsetf(ios::scientific); /*----------------------------------------------------*/ // 範例程式7-12 // 清除格式化旗標 // 陳慶瀚,2001 /*----------------------------------------------------*/ #include <iostream.h> void main() { int x=123; float y=123.23; cout << x
<< " " << y <<endl; //設定格式化旗標前的輸出
cout.setf(ios::showpos);
cout.setf(ios::scientific); cout << x
<< " " << y <<endl; //設定格式化旗標後的輸出
cout.unsetf(ios::showpos); cout << x
<< " " << y <<endl; //清除格式化旗標ios::showpos後的輸出 } 這個程式的執行結果如下: 123 123.23 +123 +1.232300e+02 123 1.232300e+02 使用串流物件的格式化成員函式 串流物件(fstream, ifstream, ofstream, cin和cout)可以使用源於ios的三個成員函式來指定輸出資料的寬度、填充字元或小數點後面的輸出位數等格式。這三個函式分別是: int width(int len); width(int len)是用來設定輸出數值的欄位寬度,這裡的欄位指字元空間的個數。當它被呼叫時,除了設定往後該串流物件所輸出的資料的寬度均為len之外,同時也傳回原本所用的寬度。 輸出浮點數的資料時,我們可以使用precision(int num)指定顯示小數點後面num位數,num的預設值是6,也就是說,如果我們不設定precision(),則所有的浮點數資料都會顯示到小數點後面6位數。 最後,如果想填補一些資料間的空格,可以使用fill(char ch)。這裡ch是我們想要填入的字元或符號。 /*----------------------------------------------------*/ // 範例程式7-13 // 使用串流物件的格式化成員函式 // 陳慶瀚,2001 /*----------------------------------------------------*/ #include <iostream.h> void main() int x=123; float y=123.23; cout.setf(ios::scientific); cout << x << " "
<< y << "\n"; cout.precision(2); // 浮點數輸出精度到小數點後面兩位數 cout.width(10); // 每個資料使用10個字元空間 cout << x << " "
<< y << "\n"; cout.width(12); // 每個資料改用12個字元空間 cout.fill('*'); // 資料前空格字元填補 * cout << y << " "
<< x << "\n"; cout << y << " "
<< x << "\n"; } 這個程式的執行結果如下: 123 1.232300e+02
123 1.23e+02 *********123 1.23e+02 ****1.23e+02 123 使用格式操作子(manipulator) 格式操作子(manipulator)是一組特殊的函式,它們可以被鑲嵌在串流I/O的陳述中。下面列出所有格式操作子:
使用這些格式操作子,必須先引入標頭檔<iomanip.h>。範例程7-14和7-15分別展示檔案輸出和螢幕輸出時格式操作子的使用範例。 /*----------------------------------------------------*/ // 範例程式7-14 // 使用格式操作子 // 陳慶瀚,2001 /*----------------------------------------------------*/ #include
<fstream.h> #include
<iomanip.h> void
main() { ofstream out("test"); //將格式操作子嵌入輸出陳述(out<<......)中 out << setiosflags(ios::fixed); out << setprecision(2) <<
1000.243 << endl; out << setw(20) << "Hello
there."; } 這個程式的執行結果如下: 1000.24 Hello there. /*----------------------------------------------------*/ // 範例程式7-15 // 使用螢幕輸出的格式操作子 // 陳慶瀚,2001 /*----------------------------------------------------*/ #include <iostream.h> 這個程式的執行結果如下: +318 +3.141590e+00 在全部的格式操作子中,只有一個格式操作子ws是專用於輸入,我們看看它的使用: /*----------------------------------------------------*/ // 範例程式7-16 // 專用於鍵盤輸入的格式操作子 // 陳慶瀚,2001 /*----------------------------------------------------*/ #include <iostream.h> ofstream out("test");
cout<<"輸入一個含有空格的字串: "; cin >> ws >> s; // 讀入字串s直到空白鍵 out << s; // 輸出s直到空白鍵 cin >> ws >> s; // 由空白鍵繼續讀入字串 out << s; // 輸出s直到空白鍵 } 這個程式的執行結果如下: 輸入一個含有空格的字串:
Hello World! 打開test檔,我們將看到 HelloWorld! /*----------------------------------------------------*/ // 範例程式7-17 // 專用於檔案輸入的格式操作子 // 陳慶瀚,2001 /*----------------------------------------------------*/ #include <fstream.h> #include <iomanip.h> void main() { char s[100]; ifstream in("7-17.cpp"); while(in) // 如果檔案物件指標不在最底部位置 { in >> ws >> s;
// 讀入字串s直到空白鍵 cout << s;
// 輸出s直到空白鍵 } } 這個程式的執行結果如下: #include<fstream.h> #include<iomanip.h> voi dmain() { chars[100]; ifstreamin("7-17.cpp"); while(!in) { in>>ws>>s;//讀入字串s直到空白鍵 out<<s;//輸出s直到空白鍵 } } 課堂練習TD7-1: 將九九乘法表輸出至99.txt檔案。 課堂練習TD7-2: 宣告一個9x9大小的整數二維陣列,將值從9x9.txt檔案讀入,計算所有陣列值總和並輸出至螢幕。 |
||||||||||||||||||||||||||||||||||||||||||||
計算機概論:C/C++程式設計 義守大學電機系 陳慶瀚 |