12 資料流與檔案的存取 如果程式所處理的資料只能寫在原始程式內部,或以互動的方式由鍵盤逐一輸入,則功能將很有限。本章探討如何從檔案讀取資料,以及將處理後的資料存入檔案的方法。

Slides:



Advertisements
Similar presentations
第一單元 建立java 程式.
Advertisements

計算機程式語言實習課.
第 2 章 初探 C++.
第11章 输入输出流类.
第4章 数组 数组是由一定数目的同类元素顺序排列而成的结构类型数据 一个数组在内存占有一片连续的存储区域 数组名是存储空间的首地址
流类库与输入/输出 输入/输出标准流类 文件流类 串流类 输入/输出成员函数 用户自定义类型的输入/输出.
File Access 井民全製作.
C++的檔案處理 綠園.
題目:十六對一多工器 姓名:李國豪 學號:B
JAVA 程式設計與資料結構 第六章 輸出與輸入.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第八﹑九章 I/O系統 檔案I/O的基本概念 格式化I/O 建立自訂的嵌入子 建立自訂的擷取子 自訂I/O與檔案.
C++语言程序设计 C++语言程序设计 第四章 数组及自定义数据类型 C++语言程序设计.
1. 檔案File  開新New  檔案Empty File (再另存新檔D:\hello.c)
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
C語言簡介 日期 : 2018/12/2.
前處理指令可以要求前處理器 (preprocessor) 在程式編譯之前,先進行加入其它檔案的內容、文字取代以及選擇性編譯等工作。
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
類別(class) 類別class與物件object.
SQL Stored Procedure SQL 預存程序.
第9章 C++的文件操作 “文件”,一般是指内存以外的存储介质上一批数据的集合。C++在语言层次上提供了文件操作的一系列函数用于完成文件的操作,打开、关闭文件,读取、写入文件数据等操作。 1。字符文件与二进制文件 字符文件:又称ASCII文件或文本TEXT文件,它是以一个字节存放一个ASCII码,代表一个字符。例如,32767需要使用5个字节表示,即:
计算机网络讲义 第5章 批量数据处理—数组 一维数组 排序和查找 二维数组 字符串.
2017 Operating Systems 作業系統實習 助教:陳主恩、林欣穎 實驗室:720A.
檔案 將資料存入磁碟或由磁碟取出資料的方式, 稱為檔案存取處理。 C語言的檔案處理 C++語言的檔案處理.
第八章 文件 引述 输入输出流和文件概述 文件操作 流的格式化输出 程序举例 本章小节.
第3讲 C++程序控制结构 3.1 顺序结构 3.2 分支结构 3.3 循环结构 3.4 转向控制 3.5 综合案例分析.
第二章 SPSS的使用 2.1 啟動SPSS系統 2.2 結束SPSS系統 2.3 資料分析之相關檔案 2.4 如何使用SPSS軟體.
第13章 输入输出流 王雪晶.
Java 程式設計 講師:FrankLin.
第九章 C++的I/O流库 9.1 流 9.2 磁盘文件 9.3 程序举例.
程序的三种基本结构 if条件分支语句 switch多路开关语句 循环语句 循环嵌套 break,continue和goto语句
第八章 文件 引述 输入输出流和文件概述 文件操作 流的格式化输出 程序举例 本章小节.
C++语言程序设计 第十一章 流类库与输入/输出.
切換Dev c++顯示語言 工具->環境選項(V)->介面->language (Chinese TW)
程式設計實習課(四) ----C 函數運用----
第一單元 建立java 程式.
選擇性結構 if-else… switch-case 重複性結構 while… do-while… for…
第 14 章 輸出與輸入.
第十三讲 文件流与 输出输入重载.
第14章 输入输出与文件 输入输出是指程序与外部设备交换信息 C++把输入输出看成是一个数据流 输入流:外围设备流向内存的数据
開始使用Visual C++.
第 19 章 XML記憶體執行模式.
雲端計算.
第7章 输入/输出流 文件和I/O流概述 标准I/O流的对象及其成员函数 文件流.
程式結構&語法.
輸入&輸出 函數 P20~P21.
第一次Labview就上手 參考書籍: LabVIEW for Everyone (Jeffrey Travis/Jim Kring)
C++语言程序设计 C++语言程序设计 第三章 控制语句 第十一组 C++语言程序设计.
挑戰C++程式語言 ──第8章 進一步談字元與字串
物件導向程式設計 CH2.
C++的檔案處理 綠園.
Class & Object 靜宜大學資工系 蔡奇偉副教授 ©2011.
引用檔案.
C++程式設計入門 變數與運算子 作者:黃建庭.
File Input and Output Chap. 11: 施威銘的書 Chap. 7: K&R.
挑戰C++程式語言 ──第7章 輸入與輸出.
流程控制:Switch-Case 94學年度第一學期‧資訊教育 東海大學物理系.
C/C++基礎程式設計班 C++: 物件的使用、參考、重載函式 講師:林業峻 CSIE, NTU 3/28, 2015.
字 串 9 子曰:「質勝文則野,文勝質則史。 文質彬彬,然後君子。」 《論語﹒雍也第六》
#include <iostream.h>
Chapter 15 檔案存取 LabVIEW中的檔案存取函數也可將程式中的資料儲存成Excel或Word檔。只要將欲存取的檔案路徑位址透過LabVIEW中的路徑元件告訴檔案存取函數後,LabVIEW便可將資料存成Excel或Word檔;當然也可以將Excel或Word檔的資料讀入LabVIEW的程式中。
選擇性結構 if-else… switch-case 重複性結構 while… do-while… for…
2018 Operating Systems 作業系統實習 助教:林欣穎 實驗室:720A.
第2章 文件操作 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
第四章 陣列、指標與參考 4-1 物件陣列 4-2 使用物件指標 4-3 this指標 4-4 new 與 delete
String類別 在C語言中提供兩種支援字串的方式 可以使用傳統以null結尾的字元陣列 使用string類別
變數與資料型態  綠園.
Unix指令4-文字編輯與程式撰寫.
InputStreamReader Console Scanner
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
Presentation transcript:

12 資料流與檔案的存取 如果程式所處理的資料只能寫在原始程式內部,或以互動的方式由鍵盤逐一輸入,則功能將很有限。本章探討如何從檔案讀取資料,以及將處理後的資料存入檔案的方法。

資料流與檔案的存取 12.1 資料流 12.2 檔案的存取 12.3 檔案的存取模式 12.4 資料的讀取與寫入 12.1 資料流 12.2 檔案的存取 12.3 檔案的存取模式 12.4 資料的讀取與寫入 12.5 檔案內容的位置標記 12.6 將檔案的存取寫成函數

資料流 (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

資料流 (stream)和資料流物件(stream object) cout是聯結程式和顯示器的管道,而cin是聯結程式和鍵盤的管道。 單向的資料流通管道為資料流 (stream)。 cin 是一個輸入資料流物件 (input stream object) 。 cout 是一個輸出資料流物件 (output stream object)。

物件 (object) 和類別 (class) 類別是一種廣義的資料型態,它可以由程式寫作者自行定義。 由類別定義的「物件」不僅包括資料,而且還包括與物件進行互動所需要的各種函數。 cin和cout分別屬於istream和ostream兩個類別。我們不需要定義cin和cout,因為它們是最常用的預設物件。

資料流 (stream) 與硬體之間的關係圖 驅動程式 驅動程式 (drivers) 是作業系統 (例如Windows和Linux) 的一部份,用來與硬體 (譬如鍵盤和顯示器) 溝通,以處理硬體裝置與記憶體之間的資料流動。如下圖所示: 資料流 (stream) 與硬體之間的關係圖

使用成員函數 (member functions) 的語法 類別 (Class) 內部所定義的各種函數稱為成員函數 (member functions) 或方法 (methods)。 敘述 cin.get(Ch); 裏,句點「.」稱為成員運算符號 (member operator),它的前面是物件的名稱,而其後是成員函數的名稱。

呼叫物件cin的成員函數get()

檔案 在一個名稱之下,內含有資料的獨立儲存單位。檔案通常儲存於硬碟、磁片、光碟、磁帶或 MO 等媒體上。

檔案的存取 程式開頭要加入標頭檔: <fstream>,以含入必要的類別宣告。 必需明確地宣告和定義讀寫檔案所需的管道 (亦即資料流)。 例如: 要讀取檔案時,定義類別為ifstream 的輸入型檔案資料流: ifstream FileInput; 要寫入檔案時,則需定義類別為ofstream的輸出型檔案資料流: ofstream FileOutput; 讀寫檔案前,需要先執行將檔案「開啟」 (open) 的動作。讀寫完畢後,最好執行將檔案「關閉」(close) 的動作。

檔案和程式、資料流之間的關係

資料存取的語法 一旦檔案被開啟,則資料存取的語法和先前cin、cout的用法相同。例如: FileInput >> x; FileOutput << x << endl 程式內部所直接使用的是各個「已經聯結到特定檔案的檔案資料流」,而不再提及檔案的名稱。

將資料流聯結到檔案的語法 例如,在檔案開啟時將敘述寫成: 檔案關閉時,則不用再寫出檔案名稱,只需寫成: FileInput.open(“FileA.txt”); 檔案關閉時,則不用再寫出檔案名稱,只需寫成: FileInput.close();

範例程式TaxFile.cpp 從檔案Income.txt將收入的數值讀到變數Income裏,再呼叫函數CalculateTax() 以計算稅額Tax,最後把稅額的數值輸出到顯示器,並同時存到檔案Tax.txt裏。 示範了如何宣告資料流,如何開啟和關閉檔案,以及如何在檔案裏存取資料的細節。

範例程式 檔案 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 );

if (!FileInput) { cout << "檔案: " << FileNameIn << " 開啟失敗!" << endl; exit(1); } if (!FileOutput) cout << "檔案: " << FileNameOut << " 存檔失敗!" << endl; exit(1); FileInput >> Income; Tax = CalculateTax(Income); cout << "您要繳的綜合所得稅是: " << Tax << " 元";

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; }

操作結果 您要繳的綜合所得稅是:50715.2元

檔案的存取模式 1. create (創造) 和replace (取代): 如果檔案不存在,要不要產生一個新的檔案,如果檔案已經存在,要不要將其取代。 2. append (附加) 和 replace (取代): 從資料流輸入的資料要接在原來的內容之後,還是要取代原來的內容。

另外一種檢查開檔動作有沒有失敗的語法 將開檔部份的敘述改寫如下: FileInput.open (FileNameIn, ios::nocreate); if (FileInput.fail()) { cout << "檔案: " << FileNameIn << " 開啟失敗!" << endl; exit(1); }

結合資料流的宣告敘述和開檔的動作 如果檔案資料流FileInput在程式中只跟一個檔案聯結,則可以進一步寫成: ifstream FileInput (FileName, ios::nocreate); 參數 nocreate 又稱為模式指示參數 (mode indicator)。

常用的模式指示參數(mode indicator) 開檔模式 ios::in 將檔案開啟成輸入模式。 ios::out 將檔案開啟成輸出模式,如果已有同名舊檔則將其取代。 ios::app 開啟為append(添加)模式。 ios::ate 移到所開啟檔案的結尾處。 ios::binary 將開啟的檔案內容視為二進位碼。 (預設模式為「文字」) ios::trunc 如果檔案已經存在,則將其內容清除。 ios::nocreate 只用來開啟舊檔作為輸出之用,如果檔案不存在就放棄。 ios::noreplace 只用來開啟新檔作為輸出之用,如果已有舊檔就放棄。

統一使用fstream類別其後區別該資料流的方向 fstream FileInput; fstream FileOutPut; FileInput.open(FileName, ios::in); FileOutput.open(FileName, ios::out);

結合模式指示參數 進一步決定「如果要開啟以供輸入的檔案不存在」的處理方式,使用「或」 (也就是or) 的語法: FileInput.open(FileName, ios::in | ios::nocreate);

EOF (end-of-file) 檔案的結束記號。 EOF為標頭檔 <fstream> 內定義的常數。 它在Windows和DOS作業系統都是使用第26個ASCII字元‘Ctrl-Z’,在某些作業系統內EOF的值設為 –1。

範例程式ConvFile.cpp 使用本節介紹的語法進行讀檔與存檔的操作。 首先從檔案Original.txt 逐一讀進字母,再經 <cctype> 中的函數toupper()將字母轉換為大寫字母後,逐一存進檔案Converted.txt 中。

範例程式 檔案 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() {

char C; fstream FileInput(FileNameIn, ios::in); if (!FileInput) { cout << "檔案: " << FileNameIn << " 開啟失敗!" << endl; exit(1); } fstream FileOutput(FileNameOut, ios::out); if (!FileOutput) cout << "檔案: << FileNameOut << " 存檔失敗!" << endl;

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 ; case 5: FileOutput << "Other" << endl; default: cout << "程式有問題!" << endl; }

FileOutput.close(); FileInput.close(); cout << "成功存於檔案 " << FileNameOut << " 內.\n"; return 0; } // ---函數 Sort() 的定義--------- int Sort(char X) { if (isupper(X)) else if (islower(X)) return 1;

else if (isdigit(X)) return 2; else if (isspace(X)) return 3; else if (ispunct(X)) return 4; else return 5; }

操作結果 (在顯示器上會看到下列訊息:) 成功存於檔案 Conerted.txt 內. 檔案Original.txt 的內容是: I love you, certainly. 檔案Converted.txt 的內容是: I LOVE YOU, CERTAINLY.

檔案資料流 fstream 的成員函數 表12.4 fstream的成員函數 成員函數名稱 用 途 get(Ch) 用 途 get(Ch) 從輸入資料流讀取一個字元。 getline(S1,N,‘\n’) 從輸入資料流讀取字元,並將其依序置於字串S1中,直到已讀取(N-1)個字元,或遇到字元‘\n’。 peek() 從輸入資料流中檢查下一個字元,但不將其從資料流中取出。 put(Ch) 將一個字元置於輸出資料流中 putback(Ch) 在不影響檔案內容的情況下,對輸入資料流放回一個字元。 eof() 如果讀取的動作超過EOF(end-of-file,檔案結尾)則函數值為true。 ignore(N) 跳過下面N個字元。如果不寫參數,而寫成ignore(),表示跳過下個字元。

範例程式RWFiles.cpp 從檔案 Record.txt 將字串資料和數值資料分別讀到字串陣列Name 和數值陣列Score裏,再單獨對Score進行計算,最後把字串和數值存到檔案 Saved.txt 裏。 這個程式示範輸入資料流的成員函數peek()的使用細節,它用來檢查即將讀入的字元是否為 EOF。

範例程式 檔案 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];

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++; }

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;

操作結果 (在顯示器上會看到下列訊息:) 成功存於檔案Saved.txt 內. 檔案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為結尾的意思)

配合檔案內容的位置標記的成員函數 表12.5.1 配合檔案內容的位置標記的成員函數 表12.5.1 配合檔案內容的位置標記的成員函數 「位置標記」以及「偏移量」的資料型態必需是長整數 (long int)。 各成員函數名稱中的g是get (取得),而p是put (放入) 的簡寫。 成員函數 功 能 seekg(偏移量,模式) 在輸入檔案中,將位置標記依模式所規定的起點,移到偏移量所定的位置。 seekp(偏移量,模式) 在輸出檔案中,將位置標記依模式所規定的起點,移到偏移量所定的位置。 tellg() 從輸入檔案中,獲得位置標記目前所在的位置。 tellp() 從輸出檔案中,獲得位置標記目前所在的位置。

位置標記的成員函數舉例 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); :將位置標記移到輸入檔案結尾的位置。

使用成員函數tellg()從檔案資料流中獲得已開啟檔案中的字元數目 例如: ifstream FileInput (“Data.txt”); // 開啟檔案 Data.txt long CharNum; FileInput.seekg(0L, ios::end); // 移到檔案結束的地方 CharNum = FileInput.tellg(); // 獲得字元數目 就可以得到 Data.txt 中的字元數目,並將它儲存在長整數CharNum中。

使用seekg() 以移動位置標記在已開啟的檔案中游走 把位置標記先移到檔案結尾處,再逐一往前移動,把既有檔案中的字元次序顛倒過來: 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中。

範例程式 檔案 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); if (!FileOutput) cout << “檔案” << FileNameOut  << " 存檔失敗!" << endl; cout << “檔案” << 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;

範例程式FileAccess.cpp WriteString(): 使用檔案以儲存字串的函數。 WriteData(): 使用檔案以儲存數字的函數。 以字串為參數傳遞檔案名稱,參數Mode則是模式指示參數 (mode indicator),當Mode為1時是append (附加),Mode為0時是replace (取代)。

範例程式FileAccess.cpp: 函數Add_Txt() 這個函數可以自動偵測做為檔案名稱的字串有沒有延伸檔名,並加以修正。 這個函數使用了<cstring> 裹面宣告的函數strcpy()。

範例程式 檔案 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 () {

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; }

// --- 函數 Add_Txt() 的定義 ------------ void Add_Txt(char *Fname) { int i = 0; while ((Fname[i] != 0) && (Fname[i] != '.')) i++; strcpy(Fname+i,".txt"); }

// --- 函數 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);} FileOutput << String; FileOutput.close(); cout << "成功存於檔案 " << FileNameOut << " 內." << endl; }

FileOutput << "\n以下共有 " << Size << " 組數據:\n"; // --- 函數 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"; for (int i = 0; i<Size; i++)  FileOutput << Data[i] << endl; FileOutput.close(); cout << "成功存於檔案 " << FileNameOut << " 內."<< endl; }

操作結果 (在顯示器上會看到下列訊息) 成功存於檔案 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 0.316667

範例程式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);

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);

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 ";

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 << “檔案: ” << FileNameOut << “ 存檔 失敗!\n"; exit(1); } FileOutput << String; FileOutput.close(); cout << "成功存於檔案 " << FileNameOut << " 內.\n"; return;

範例程式 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 () {

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);

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];

} // === 函數 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 << " 存檔 失敗!\n"; exit(1);} FileOutput << String; FileOutput.close(); cout << "成功存於檔案 " << FileNameOut << " 內." << endl;

操作結果 執行Encoding.exe在顯示器上會看到下列訊息: 執行Decoding.exe在顯示器上會看到下列訊息: 檔案:OriginalText.txt開啟成功, 下列是原有檔案內容:  I love you. 編碼後的內容是:  Y WQFZ IQR 成功存於檔案EncodedText.txt內. 檔案:EncodedText.txt開啟成功, 下列是原有檔案內容: Y WQFZ IQR 解碼後的內容是: I LOVE YOU 成功存於檔案 DecodedText.txt 內.

操作結果 檔案OriginalText.txt的內容是: 檔案EncodedText.txt的內容是: I LOVE YOU 檔案EncodedText.txt的內容是: Y WQFZ IQR 檔案DecodedText.txt的內容是: