12 資料流與檔案的存取 如果程式所處理的資料只能寫在原始程式內部, 或以互動的方式由鍵盤逐一輸入, 則功能將很有限 本章探討如何從檔案讀取資料, 以及將處理後的資料存入檔案的方法 1/69 資料流與檔案的存取 12.1 12.2 12.3 12.4 12.5 12.6 資料流檔案的存取檔案的存取模式資料的讀取與寫入檔案內容的位置標記將檔案的存取寫成函數 2/69
3/69 資料流 (stream) 回顧標準的輸出入管道 cout 和 cin: 範例程式檔案 BasicIO.cpp // BasicIO.cpp #include <iostream> using namespace std; int main () int N; cout << 請輸入一個整數 : << endl; cin >> N; cout << 您輸入的是 << N << endl; return 0; 操作結果 請輸入一個整數 : 4563 您輸入的是 4563 4/69
資料流 (stream) 和資料流物件 (stream object) cout 是聯結程式和顯示器的管道, 而 cin 是聯結程式和鍵盤的管道 單向的資料流通管道為資料流 (stream) cin 是一個輸入資料流物件 (input stream object) cout 是一個輸出資料流物件 (output stream object) 5/69 物件 (object) 和類別 (class) 物件 (object), 其原文有 個體 對象 等多種意涵 類別是一種廣義的資料型態, 它可以由程式寫作者自行定義 由類別定義的 物件 不僅包括資料, 而且還包括與物件進行互動所需要的各種函數 cin 和 cout 分別屬於 istream 和 ostream 兩個類別 我們不需要定義 cin 和 cout, 因為它們是最常用的預設物件 6/69
驅動程式 驅動程式 (drivers) 是作業系統 ( 例如 Windows 和 Linux) 的一部份, 用來與硬體 ( 譬如鍵盤和顯示器 ) 溝通, 以處理硬體裝置與記憶體之間的資料記憶體流動 如下圖所示 : C++ 程式 cout cin Buffer Buffer 顯示器 鍵盤 7/69 資料流 (stream) 與硬體之間的關係圖 使用成員函數 (member functions) 的語法 類別 (Class) 內部所定義的各種函數稱為成員函數 (member functions) 或方法 (methods) 敘述 cin.get(ch); 裏, 句點. 稱為成員運算符號 (member operator), 它的前面是物件的名稱, 而其後是成員函數的名稱 8/69
呼叫物件 cin 的成員函數 get() cin.get (Ch); 成員函數 物件名稱 引數 9/69 檔案 在一個名稱之下, 內含有資料的獨立儲存單位 檔案通常儲存於硬碟 磁片 光碟 磁帶或 MO 等媒體上 10/69
11/69 檔案的存取 1. 程式開頭要加入標頭檔 : <fstream>, 以含入必要的類別宣告 2. 必需明確地宣告和定義讀寫檔案所需的管道 ( 亦即資料流 ) 例如 : 要讀取檔案時, 定義類別為 ifstream 的輸入型檔案資料流 : ifstream FileInput; 要寫入檔案時, 則需定義類別為 ofstream 的輸出型檔案資料流 : ofstream FileOutput; 讀寫檔案前, 需要先執行將檔案 開啟 (open) 的動作 讀寫完畢後, 最好執行將檔案 關閉 (close) 的動作 檔案和程式 資料流之間的關係 記憶體 驅動程式 暫存器 (register) 輸入檔案資料流 輸出檔案資料流 C++ 程式 儲存裝置 12/69
資料存取的語法 一旦檔案被開啟, 則資料存取的語法和先前 cin cout 的用法相同 例如 : FileInput >> x; FileOutput << x << endl 程式內部所直接使用的是各個 已經聯結到特定檔案的檔案資料流, 而不再提及檔案的名稱 13/69 將資料流聯結到檔案的語法 例如, 在檔案開啟時將敘述寫成 : FileInput.open( FileA.txt ); 檔案關閉時, 則不用再寫出檔案名稱, 只需寫成 : FileInput.close(); 14/69
範例程式 TaxFile.cpp 從檔案 Income.txt 將收入的數值讀到變數 Income 裏, 再呼叫函數 CalculateTax() 以計算稅額 Tax, 最後把稅額的數值輸出到顯示器, 並同時存到檔案 Tax.txt 裏 示範了如何宣告資料流, 如何開啟和關閉檔案, 以及如何在檔案裏存取資料的細節 15/69 範例程式 檔案 TaxFile.cpp // TaxFile.cpp #include <iostream> #include <fstream> using namespace std; double CalculateTax(double); // 函數的宣告 // --- 主程式 ------------------------ int main() char* FileNameIn = "Income.txt"; // 以字串的方式宣告檔名 char* FileNameOut = "Tax.txt"; double Income, Tax; ifstream FileInput; ofstream FileOutput; FileInput.open ( FileNameIn ); FileOutput.open( FileNameOut ); 16/69
17/69 if (!FileInput) cout << " 檔案 : " << FileNameIn << " 開啟失敗!" << endl; exit(1); if (!FileOutput) cout << " 檔案 : " << FileNameOut << " 存檔失敗!" << endl; exit(1); FileInput >> Income; Tax = CalculateTax(Income); cout << " 您要繳的綜合所得稅是 : " << Tax << " 元 "; 18/69 FileOutput << " 您要繳的綜合所得稅是 : " << Tax << " 元 "; FileInput.close(); // 關閉輸入檔案 FileOutput.close(); // 關閉輸出檔案 return 0; // --- 函數 CalculateTax() 的定義 ----- // 改寫自 4.4 節 巢狀 if-else 敘述 // 程式 Tax.cpp 以計算稅額 double CalculateTax(double GIncome) double Tax; if (GIncome < 0.0) cout << " 您輸入的綜合所得淨額沒有意義!\n"; else if (GIncome < 330000.0) Tax = GIncome * 0.06;
else if (GIncome < 890000.0) Tax = GIncome * 0.13-23100; else if (GIncome < 1780000.0) Tax = GIncome * 0.21-94300; else if (GIncome < 3340000.0) Tax = GIncome * 0.3-254500; else Tax = GIncome * 0.4-588500; return Tax; 19/69 操作結果 您要繳的綜合所得稅是 :50715.2 元 20/69
檔案的存取模式 1.create ( 創造 ) 和 replace ( 取代 ): 如果檔案不存在, 要不要產生一個新的檔案, 如果檔案已經存在, 要不要將其取代 2.append ( 附加 ) 和 replace ( 取代 ): 從資料流輸入的資料要接在原來的內容之後, 還是要取代原來的內容 21/69 另外一種檢查開檔動作有沒有失敗的語法 將開檔部份的敘述改寫如下 : 22/69 FileInput.open (FileNameIn, ios::nocreate); if (FileInput.fail()) cout << " 檔案 : " << FileNameIn << " 開啟失敗!" << endl; exit(1);
結合資料流的宣告敘述和開檔的動作 如果檔案資料流 FileInput 在程式中只跟一個檔案聯結, 則可以進一步寫成 : ifstream FileInput (FileName, ios::nocreate); 參數 nocreate 又稱為模式指示參數 (mode indicator) 23/69 常用的模式指示參數 (mode indicator) 模式指示參數 ios::in ios::out ios::app ios::ate ios::binary ios::trunc ios::nocreate ios::noreplace 開檔模式將檔案開啟成輸入模式 將檔案開啟成輸出模式, 如果已有同名舊檔則將其取代 開啟為 append( 添加 ) 模式 移到所開啟檔案的結尾處 將開啟的檔案內容視為二進位碼 ( 預設模式為 文字 ) 如果檔案已經存在, 則將其內容清除 只用來開啟舊檔作為輸出之用, 如果檔案不存在就放棄 只用來開啟新檔作為輸出之用, 如果已有舊檔就放棄 24/69
統一使用 fstream 類別其後區別該資料流的方向 fstream FileInput; fstream FileOutPut; FileInput.open(FileName, ios::in); FileOutput.open(FileName, ios::out); 25/69 結合模式指示參數 進一步決定 如果要開啟以供輸入的檔案不存在 的處理方式, 使用 或 ( 也就是 or) 的語法 : FileInput.open(FileName, ios::in ios::nocreate); 26/69
EOF (end-of-file) 檔案的結束記號 EOF 為標頭檔 <fstream> 內定義的常數 它在 Windows 和 DOS 作業系統都是使用第 26 個 ASCII 字元 Ctrl-Z, 在某些作業系統內 EOF 的值設為 1 27/69 範例程式 ConvFile.cpp 使用本節介紹的語法進行讀檔與存檔的操作 首先從檔案 Original.txt 逐一讀進字母, 再經 <cctype> 中的函數 toupper() 將字母轉換為大寫字母後, 逐一存進檔案 Converted.txt 中 28/69
範例程式 檔案 ConvFile.cpp // ConvFile.cpp #include <iomanip> #include <iostream> #include <fstream> #include <cctype> using namespace std; char* FileNameIn = "Original.txt"; char* FileNameOut = "Converted.txt"; // --- 函數 Sort() 的宣告 ---- int Sort(char X); // --- 主程式 ------------------------ int main() 29/69 30/69 char C; fstream FileInput(FileNameIn, ios::in); if (!FileInput) cout << " 檔案 : " << " 開啟失敗!" << endl; exit(1); << FileNameIn fstream FileOutput(FileNameOut, ios::out); if (!FileOutput) cout << " 檔案 : << " 存檔失敗!" << endl; exit(1); << FileNameOut
31/69 while ((C = FileInput.get())!= EOF) switch (Sort(C)) case 1: FileOutput << char(toupper(c)); break; case 0: case 2: case 3: case 4: FileOutput << C ; break; case 5: FileOutput << "Other" << endl; break; default: cout << " 程式有問題!" << endl; FileOutput.close(); FileInput.close(); cout << " 成功存於檔案 " << FileNameOut << " 內.\n"; return 0; // --- 函數 Sort() 的定義 --------- int Sort(char X) if (isupper(x)) return 0; else if (islower(x)) return 1; 32/69
else if (isdigit(x)) return 2; else if (isspace(x)) return 3; else if (ispunct(x)) return 4; else return 5; 33/69 操作結果 ( 在顯示器上會看到下列訊息 :) 成功存於檔案 Conerted.txt 內. 檔案 Original.txt 的內容是 : I love you, certainly. 檔案 Converted.txt 的內容是 : I LOVE YOU, CERTAINLY. 34/69
檔案資料流 fstream 的成員函數 成員函數名稱 get(ch) 表 12.4 fstream 的成員函數 用途從輸入資料流讀取一個字元 35/69 getline(s1,n, \n ) peek() put(ch) putback(ch) eof() ignore(n) 從輸入資料流讀取字元, 並將其依序置於字串 S1 中, 直到已讀取 (N-1) 個字元, 或遇到字元 \n 從輸入資料流中檢查下一個字元, 但不將其從資料流中取出 將一個字元置於輸出資料流中 在不影響檔案內容的情況下, 對輸入資料流放回一個字元 如果讀取的動作超過 EOF(end-of-file, 檔案結尾 ) 則函數值為 true 跳過下面 N 個字元 如果不寫參數, 而寫成 ignore(), 表示跳過下個字元 範例程式 RWFiles.cpp 從檔案 Record.txt 將字串資料和數值資料分別讀到字串陣列 Name 和數值陣列 Score 裏, 再單獨對 Score 進行計算, 最後把字串和數值存到檔案 Saved.txt 裏 這個程式示範輸入資料流的成員函數 peek() 的使用細節, 它用來檢查即將讀入的字元是否為 EOF 36/69
範例程式 檔案 RWFiles.cpp // RWFiles.cpp #include <iostream> #include <iomanip> #include <fstream> using namespace std; char* FileNameIn = "Record.txt"; char* FileNameOut = "Saved.txt"; // --- 主程式 ------------------------ int main() const int MaxNum = 40; const int MaxSize = 20; char Name [MaxNum][MaxSize]; int Score[MaxNum]; 37/69 fstream FileInput(FileNameIn, ios::in); if (!FileInput) cout << " 檔案 : " << FileNameIn << " 開啟失敗!" << endl; exit(1); fstream FileOutput(FileNameOut, ios::out); if (!FileOutput) cout << " 檔案 : " << FileNameOut << " 存檔失敗!" << endl; exit(1); int Count=0; while (FileInput.peek()!= EOF && (Count < MaxNum)) FileInput >> Name[Count] >> Score[Count]; Count++; 38/69
for (int i=0; i< Count; i++) Score[i] = Score[i]*0.8+20; FileOutput << '(' << i+1 << ')' << setw(12) << Name[i] << " " << setw(5) << Score[i] << endl; FileOutput.close(); FileInput.close(); cout << " 成功存於檔案 " << FileNameOut << " 內." << endl; return 0; 39/69 操作結果 ( 在顯示器上會看到下列訊息 :) 成功存於檔案 Saved.txt 內. 40/69 檔案 Record.txt 的內容是 : 王能治 87 李大為 92 蕭飛雪 78 張心怡 86 檔案 Saved.txt 的內容是 : (1) 王能治 89 (2) 李大為 93 (3) 蕭飛雪 82 (4) 張心怡 88
檔案內容的位置標記 (File Position Marker) 位置標記使用 相對位置 的觀念 : 從某個位置當起點, 再加上偏移量 (offset) 以到達所要的位置 按照起點位置的不同, 位置標記在使用上有下列三種模式 (modes of the file position marker): ios::beg 從檔案的開頭算起 (beg 為 begin 的縮寫 ) ios::cur 從目前位置算起 (cur 為 current 的縮寫 ) ios::end 從檔案結尾算起 (end 為結尾的意思 ) 41/69 配合檔案內容的位置標記的成員函數 表 12.5.1 配合檔案內容的位置標記的成員函數 成員函數 功 能 seekg( 偏移量, 模式 ) seekp( 偏移量, 模式 ) tellg() tellp() 在輸入檔案中, 將位置標記依模式所規定的起點, 移到偏移量所定的位置 在輸出檔案中, 將位置標記依模式所規定的起點, 移到偏移量所定的位置 從輸入檔案中, 獲得位置標記目前所在的位置 從輸出檔案中, 獲得位置標記目前所在的位置 位置標記 以及 偏移量 的資料型態必需是長整數 (long int) 各成員函數名稱中的 g 是 get ( 取得 ), 而 p 是 put ( 放入 ) 的簡寫 42/69
位置標記的成員函數舉例 1. FileOutput.seekp(5L, ios::cur); : 將位置標記在輸出檔案中從目前的位置往前移動 5 個字元的距離 2. FileOutput.seekp(2L, ios::beg); : 將位置標記在輸出檔案中移到第 3 個字元的位置 3. FileOutput.seekp(-5L, ios::end); : 將位置標記在輸出檔案中移到倒數第 5 個字元的位置 4. FileInput.seekg(0L, ios::beg); : 將位置標記移到輸入檔案開頭的位置 5. FileInput.seekg(0L, ios::end); : 將位置標記移到輸入檔案結尾的位置 43/69 使用成員函數 tellg() 從檔案資料流中獲得已開啟檔案中的字元數目 例如 : ifstream FileInput ( Data.txt ); Data.txt // 開啟檔案 long CharNum; FileInput.seekg(0L, ios::end); CharNum = FileInput.tellg(); // 移到檔案結束的地方 // 獲得字元數目 就可以得到 Data.txt 中的字元數目, 並將它儲存在長整數 CharNum 中 44/69
使用 seekg() 以移動位置標記在已開啟的檔案中游走 把位置標記先移到檔案結尾處, 再逐一往前移動, 把既有檔案中的字元次序顛倒過來 : 45/69 long Offset; char Ch; for (Offset=1L; Offset<= CharNum; Offset++) FileInput.seekg(-Offset, ios::end); Ch = FileInput.get(); FileOutput << Ch; 範例程式 FileReverse.cpp 我們將上述倒轉檔案內容的指令寫成完整的範例程式 這個程式首先從檔案 Original.txt 讀取資料, 將檔案中的字元次序顛倒過來後, 逐一存於檔案 Reversed.txt 中 46/69
範例程式 檔案 FileReverse.cpp 47/69 // FileReverse.cpp #include <iostream> #include <iomanip> #include <fstream> using namespace std; char* FileNameIn = "Original.txt"; char* FileNameOut = "Reversed.txt"; // --- 主程式 ------------------------ int main() long CharNum, Offset; char Ch; fstream FileInput(FileNameIn, ios::in); if (!FileInput) cout << 檔案 << FileNameIn << " 開啟失敗!" << endl; exit(1); fstream FileOutput(FileNameOut, ios::out); 48/69 if (!FileOutput) cout << 檔案 cout << FileNameOut << " 存檔失敗!" << endl; exit(1); << 檔案 << FileNameIn << " 開啟成功 " << endl; FileInput.seekg(0L, ios::end); // 移到檔案結束的地方
CharNum = FileInput.tellg(); // 獲得字元數目 for (Offset=1L; Offset<= CharNum; Offset++) FileInput.seekg(-Offset, ios::end); Ch = FileInput.get(); FileOutput << Ch; FileOutput.close(); FileOutput // 關閉 FileInput.close(); FileInput // 關閉 cout << " 倒轉檔案 " << FileNameIn << " 後的內容 \n 成功存於檔案 " << FileNameOut << " 內." << endl; return 0; 49/69 50/69 範例程式 FileAccess.cpp WriteString(): 使用檔案以儲存字串的函數 WriteData(): 使用檔案以儲存數字的函數 以字串為參數傳遞檔案名稱, 參數 Mode 則是模式指示參數 (mode indicator), 當 Mode 為 1 時是 append ( 附加 ),Mode 為 0 時是 replace ( 取代 )
範例程式 FileAccess.cpp: 函數 Add_Txt() 在字串後面附加.txt 延伸檔名 這個函數可以自動偵測做為檔案名稱的字串有沒有延伸檔名, 並加以修正 這個函數使用了 <cstring> 裹面宣告的函數 strcpy() 51/69 範例程式 檔案 FileAccess.cpp // FileAccess.cpp #include <iostream> #include <iomanip> #include <fstream> using namespace std; // --- 函數的宣告 ----------------------- void Add_Txt(char *); void WriteString (char *, char *, int Mode); // Mode:(1 = append, 0 = replace) void WriteData (char *, float *, int, int Mode); // --- 主程式 ---------------------------------- int main () 52/69
const DataSize = 12; float Data [DataSize]; char FileName[20] = "SaveRecord"; char* S1 = "A long time ago..."; Add_Txt(FileName); for (int i = 0; i < DataSize; i++) Data[i]= 3.8/float(1+i); WriteString(FileName, S1, 0); WriteData(FileName, Data, DataSize, 1); return 0; 53/69 // --- 函數 Add_Txt() 的定義 ------------ void Add_Txt(char *Fname) int i = 0; while ((Fname[i]!= 0) && (Fname[i]!= '.')) i++; strcpy(fname+i,".txt"); 54/69
// --- 函數 WriteString () 的定義 -------------- void WriteString (char *FileNameOut, char *String, int Mode) ofstream FileOutput; if (Mode) FileOutput.open( FileNameOut, ios::app); else FileOutput.open( FileNameOut, ios::out); if (!FileOutput) cout << " 檔案 : " << FileNameOut << " 存檔失敗!" << endl; exit(1); 55/69 FileOutput << String; FileOutput.close(); cout << " 成功存於檔案 " << " 內." << endl; << FileNameOut // --- 函數 WriteData () 的定義 ---------------- void WriteData (char *FileNameOut, float *Data, int Size, int Mode) ofstream FileOutput; if (Mode) FileOutput.open( FileNameOut, ios::app); else FileOutput.open( FileNameOut, ios::out); if (!FileOutput) cout << " 檔案 : " << FileNameOut << " 存檔失敗!" << endl; exit(1); FileOutput << "\n 以下共有 " << Size << " 組數據 :\n"; 56/69 for (int i = 0; i<size; i++) FileOutput << Data[i] << endl; FileOutput.close(); cout << " 成功存於檔案 " << FileNameOut << " 內."<< endl;
操作結果 ( 在顯示器上會看到下列訊息 ) 成功存於檔案 SaveRecord.txt 內. 成功存於檔案 SaveRecord.txt 內. 檔案 Record.txt 的內容是 : A long time ago... 以下共有 12 組數據 : 3.8 1.9 1.26667 0.95 0.76 0.633333 0.542857 0.475 0.422222 0.38 0.345455 57/69 0.316667 58/69 範例程式 Encoding.cpp 和 Decoding.cpp 改寫 9.5 節程式 EncodeText.cpp, 將它分成兩個程式 Encoding.cpp 和 Decoding.cpp, 分別用來讀取檔案, 將檔案內容編碼或解碼後, 存於另外一個檔案中 在程式 Encoding.cpp 中, 函數 Encode() 將檔案內容編碼 在程式 Decoding.cpp 中, 函數 Decode() 將檔案內容解碼
範例程式 檔案 Encoding.cpp // Encoding.cpp #include <iostream> #include <fstream> using namespace std; // --- 函數的宣告 ---------------------- void GetString (char *FileNameIn, char *String); void Encode(char *String); void WriteString (char *, char *, int Mode); int main ()// --- 主程式 ------------------ char FileNameIn[20] = "OriginalText.txt"; char FileNameOut[20] = "EncodedText.txt"; const int MaxLength = 40; char String[MaxLength]; GetString(FileNameIn, String); 59/69 Encode(String); cout << " 編碼後的內容是 :\n" << String << endl; WriteString (FileNameOut, String, 0); return 0; // --- 函數 GetString () 的定義 ---------------- void GetString (char *FileNameIn, char *String) ifstream FileInput; FileInput.open( FileNameIn ); if (!FileInput) cout << " 檔案 : " << FileNameIn << " 開啟失敗!\n"; exit(1); 60/69
FileInput.getline(String,MaxLength); FileInput.close(); cout << " 檔案 : " << FileNameIn << " 開啟成功,\n 下列是原有檔案內容 :\n" << String << endl; // --- 函數 Encode() 的定義 -------------------- void Encode(char *String) char Codes[28]= "DOJKZCTMYPAWHUQNBVGSRFXLIE "; char ABC[28] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "; char abc[28] = "abcdefghijklmnopqrstuvwxyz "; 61/69 62/69 int i, j, Size=strlen(String); for(i=0; i< Size; i++) j=0; while( String[i]!=ABC[j] && String[i]!= abc[j] && j<26 ) j++; String[i]=Codes[j]; return; // --- 函數 WriteString () 的定義 ---------- void WriteString (char *FileNameOut, char *String, int Mode)
ofstream FileOutput; if (Mode) FileOutput.open( FileNameOut, ios::app); else FileOutput.open( FileNameOut, ios::out); if (!FileOutput) cout << 檔案 : 失敗!\n"; exit(1); << FileNameOut << 存檔 FileOutput << String; FileOutput.close(); cout << " 成功存於檔案 " << FileNameOut << " 內.\n"; return; 63/69 範例程式 2 檔案 Decoding.cpp // Decoding.cpp #include <iostream> #include <fstream> using namespace std; // --- 函數 GetString() 的宣告 ----------------- void GetString (char *FileNameIn,char *String); // --- 函數 Decode() 的宣告 ---------------------- void Decode(char *String); // --- 函數 WriteString () 的宣告 -------------- void WriteString (char *, char *, int Mode); const int MaxLength = 40; // === 主程式 ================================ int main () 64/69
char FileNameIn[20] = "EncodedText.txt"; char FileNameOut[20] = "DecodedText.txt"; char String[MaxLength]; GetString(FileNameIn, String); Decode(String); cout << " 解碼後的內容是 :\n" << String << endl; WriteString (FileNameOut, String, 0); return 0; // === 函數 GetString () 的定義 ================ void GetString (char *FileNameIn, char *String) ifstream FileInput; FileInput.open( FileNameIn ); if (!FileInput) cout<< 檔案 : << FileNameIn << 開啟失敗!\n";exit(1); FileInput.getline(String,MaxLength); 65/69 FileInput.close(); cout << " 檔案 : " << FileNameIn << " 開啟成功,\n 下列是原有檔案內容 :\n" << String << endl; // === 函數 Decode() 的定義 ================== void Decode(char *String) char Codes[28]= "DOJKZCTMYPAWHUQNBVGSRFXLIE "; char ABC[28] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "; int i, j, Size = strlen(string); for (i=0; i<size;i++) j=0; while (String[i]!=Codes[j] && j<26) j++; String[i]=ABC[j]; 66/69
// === 函數 WriteString() 的定義 ============= void WriteString (char *FileNameOut, char *String, int Mode) ofstream FileOutput; if (Mode) FileOutput.open( FileNameOut, ios::app); else FileOutput.open( FileNameOut, ios::out); if (!FileOutput) cout << 檔案 : << FileNameOut << " 存檔失 67/69 敗!\n"; exit(1); FileOutput << String; FileOutput.close(); cout << " 成功存於檔案 " << FileNameOut << " 內." << endl; 操作結果 執行 Encoding.exe 在顯示器上會看到下列訊息 : 檔案 :OriginalText.txt 開啟成功, 下列是原有檔案內容 : I love you. 編碼後的內容是 : Y WQFZ IQR 成功存於檔案 EncodedText.txt 內. 執行 Decoding.exe 在顯示器上會看到下列訊息 : 68/69 檔案 :EncodedText.txt 開啟成功, 下列是原有檔案內容 : Y WQFZ IQR 解碼後的內容是 : I LOVE YOU 成功存於檔案 DecodedText.txt 內.
操作結果 檔案 OriginalText.txt 的內容是 : I LOVE YOU 檔案 EncodedText.txt 的內容是 : Y WQFZ IQR 檔案 DecodedText.txt 的內容是 : I LOVE YOU 69/69