補充教材
-
Upload
galena-hull -
Category
Documents
-
view
37 -
download
1
description
Transcript of 補充教材
簡介簡介標準串流輸入輸出與檔案串流輸入輸出物件
皆包含成員變數用來紀錄串流輸入輸出的狀態。◦ 這些變數稱作「狀態位元」( State bit )。
eofbit : true 代表遇到 EOF 字元。 failbit : true 代表輸入格式不正確。 badbit : true 代表輸入或輸出失敗。
任何不可回覆的錯誤產生,例如資料遺失。 goodbit :輸入輸入一切正常(換言之,以上的變數都沒
有被設為 true ), goodbit 才會被設成 true 。注意事項:
◦ 一旦 eofbit 、 failbit 或 badbit 被設為 true ,則該串流物件的輸入輸出將因此而失效。
成員函式成員函式 eof()eof() 、、 fail()fail() 、、 bad()bad() 與與good()good()呼叫串流物件的 eof() 、 fail() 、 bad()與 good() 等成員函式即可回傳各狀態位元的值◦回傳 true 或 false 。
注意事項注意事項注意事項:
◦一旦 eofbit 、 failbit 或 badbit 被設為true ,則該串流物件的輸入輸出皆會因此失效。
◦之後再以同樣的串流物件進行輸入輸出將會得到不正常的結果。 問題:如何清除串流物件的異常狀態呢?
成員函式成員函式 clear()clear()功能:接受一個引數,將特定的狀態位元予以
清除。◦ 例如:
cin.clear( ios::failbit );如不給引數,則預設會將所有的狀態位元予以
清除(設為 false ),並將 goodbit 設為true 。◦ 範例
cin.clear();
成員函式成員函式 ignore()ignore()串流輸入物件中提供成員函式 ignore ()
,其功能為:◦ 讀取串流輸入並將字元捨棄。◦ 提供一個正整數與分界字元為引數,代表捨棄的
字元數目或終止的字元。 預設的字元個數為 1 預設的分界字元為 EOF (’ \0’)
使用範例使用範例 #include <iostream> #include <limits>
using namespace std;
void main() { int x; cin >> x; if (cin.fail()) {
cin.clear();cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Error!" << endl; } else cout << "x = " << x << endl; }
使用範例二使用範例二 #include <iostream> #include <limits>
using namespace std;
void main() { int x; cin >> x; while (cin.fail()) {
cin.clear();cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Error!" << endl;cin >> x;
} cout << "x = " << x << endl; }
注意事項注意事項串流擷取運算子( >> )僅會讀取至空白字
元為止,即便狀態位元出現異常,串流輸入緩衝區中仍會遺留之前未讀入的字元。◦ 可用成員函式 ignore() 捨棄這些字元。◦ 或在狀態回復之後繼續讀取。◦ 如要讀入整行文字,或讀取固定個數的字元,可
用 cin 物件中的 get() 或 getline() 函式。 get() 與 getline() 的差別在於: get() 不會把換行符號放
進去緩衝區,但 getline() 則會。
開啟檔案開啟檔案類別 fstream 所建立的物件可以同時做為讀
取或寫入的檔案物件:file.open("test.txt", ios::out | ios::in);◦當模式既為 ios::out 又為 ios::in 時,請注
意該檔案如果不存在,並不會自動建立該檔案,反而會得到開檔失敗的情況。
◦使用該模式前,請先確認檔案是否存在,如不存在,請自行建立。
成員函式成員函式 seekg()seekg() 與與 seekp()seekp()seekg() 是在讀取檔案時,用來移動檔案指
標◦ 「 g 」代表 get
seekp() 是在寫入檔案時,用來移動檔案指標◦ 「 p 」代表 put
在「 ios::in | ios::out 」模式之下,兩者皆可使用,並請注意,不論檔案的讀取皆會同時移動到檔案指標的位置。
範例實作(範例實作( Part 1Part 1 )) #include <iostream> #include <fstream> #include <iomanip> using namespace std; void main() { fstream file("test.txt", ios::in); if (!file) {
file.clear();file.open("test.txt", ios::out);
} file.close(); file.open("test.txt", ios::out | ios::in); if (!file) {
cout << "file could not open!" << endl;return;
}…
範例實作(範例實作( Part 2Part 2 )) do { int option;
string id;int data;cout << "1) Insert 2) Output 3) Quit: ";cin >> option;if (option == 3) break;if (option == 1) { string in_ID; int in_data; cin >> in_ID; cin >> in_data; file.clear(); file.seekg(0); while (file >> id >> data) { if (id == in_ID) { // 找到重複的 ID file.seekp(-16, ios::cur);
break; } } if (file.eof()) // 遇到 EOF ,表示資料要寫到最後 file.clear(); // 再做一次 clear() 。 Why? file << setw(10) << in_ID << setw(5) << in_data << endl;}
從頭搜尋檔案。為什麼要先呼叫 clear() ?因為如果 eofbit 被設成 true ,檔案讀取會失效,所以要先清掉該位元。 file.seekg(0);一行用來將檔案指標定位到檔案開頭
用 >> 作格式化輸入可免去型態轉換的問題,但要注意 >>僅讀取至空白字元。
試說明「 file.seekp(-16, ios::cur); 」的意義。__________________________________________________
範例實作(範例實作( Part 3Part 3 )) … else if (option == 2) // 印出所有資料 { file.clear(); file.seekg(0); while (file >> id >> data) {
cout << setw(10) << id << setw(5) << data << endl; } } } while (1); file.close();}
printf()printf() 與與 scanf()scanf()呼叫 printf() 與 scanf() 可分別用來作
螢幕輸出與鍵盤輸入。◦使用前必須引入標頭檔如下:
#include <stdio.h> //C或#include <cstdio> //C++
螢幕輸出;使用螢幕輸出;使用 printf()printf() #include <stdio.h>
void main() { int x = 2; char *name = “Mary”; double g1 = 3.4; float g2 = 1.7; printf(“%s has %d classes. Her grades are %0.2e and %0.2f.\n”, name, x, g1, g2); }
相較於 cout 與 << ,使用 printf() 的差異在於,程式設計師必須要根據變數來指定格式字串;例如
整數的格式字串為 %d字串的格式字串為 %s浮點數的格式字串為 %f雙精準浮點數要用 %e
Function printf() FormatFunction printf() FormatFormat Description
%c 字元%d 十進位整數%i 十進位整數%e 浮點數, e 指數型式%E 浮點數, E指數型式%f 小數點位數 6 位之浮點數%g 印出 %f 與 %e較短者%G 印出 %f 與 %E較短者%o 無號八進位整數
Function printf() FormatFunction printf() FormatFormat Description
%% 印出百分比符號%p 以十六進位印出指標位址%s 印出字串%u 無號十進位數字%x 無號十六進位整數,以 0-f 表示%X 無號十六進位整數,以 0-F 表示%l long ,加在 d,o,u,x,X 之前
Function printf() FormatFunction printf() FormatModifier Description
- 向左齊對,如 %-4f
+ 將數值的正負符號顯示出來,如 %+f
填補空白 數值為正數時留一空白,為負時顯示負號,如 %7.2f
0 將固定欄位長度的數值前補 0 ,與 -同用時無效,如 %09f
+ 將數值的正負符號顯示出來,如 %+f
鍵盤輸入;使用鍵盤輸入;使用 scanf()scanf()
#include <stdio.h>
void main() { int age; char name[100]; float salary; printf(“Input name: ”); scanf(“%s”, name); printf(“Input age: ”); scanf(“%d”, &age); printf(“Input salary: ”); scanf(“%f”, &salary); printf(“%s is %d years old. His/her salary is %0.2f.\n”, name, age, salary); }