第12章 C++的輸入與輸出 本章投影片僅供本書上課教師使用,非經同意請勿拷貝或轉載
12-1 C++所特有的特性 C++ 另提供 ”//” 雙斜線 單行註解 表示方式。 C 若在 main() 前未加 void,表不傳回任何值。 若省略,C 的 Compiler會視為傳回整數。 C++中每個函式都必須有傳回值,即使函式沒傳回值, 也必須在函式名稱前加void,不能省略。 C 規定所有變數宣告和定義都必須放在程式開頭或所有 函式的最開頭。 C++ 允許在程式中任何地方對變數做宣告和定義。 C++ 比 C 多下列資料型別: bool(布林)、參考型別(Reference type)、類別(Class)。 P12-2
C 設定 const 變數時允許不給初值, C++設定 const 變數時必須同時設定初值。 C++ 提供 cin 和 cout 物件來做輸出入資料。 C 透過 malloc() 函式向系統要求配置記憶體, 不用時透過free() 函式將配置記憶體歸還系統。 C++ 提供 new 運算子來做動態配置記憶體, delete 運算子來釋放由 new 運算子所配置記憶體。 C++ 允許對運算子和函式重複定義(Overloading) 所謂重複定義是對相同的運算子和函式可以有不同的功能。 P12-4
12-2 C++ 程式的編輯和執行 一、使用Dev C++ 5.0整合環境 1.啟動Dev C++ 5.0整合開發環境 2.建立Console Application專案,選擇C++專案
3. 編輯程式
4. 儲存程式
5. 執行程式
6. 離開Dev C++ 5.0 執行功能表的 [檔案(F)/結束程式(X)] ,關閉 Dev C++ 5.0 整合開發環境。 7. 載入舊檔方式有二: 執行 [檔案(F)/開啟專案/一般檔案(O)…] 指令 「開啟檔案」對話方塊中指定要開啟的專案 指定開啟專案為 D:\dev\ch12\first_cpp \first_cpp.dev專案檔 執行功能表 [檔案(F)/開啟專案/一般檔案(O)…]開啟 D:\dev\ch12\ first_cpp\first_cpp.cpp 程式檔。
12-3 C++ 輸出與輸入物件介紹 C++ 輸出入透過專門負責輸出入的類別所 定義的成員函式:cin 和 cout 物件來完成。 Cin 及 cout 物件都宣告在 iostream.h 標頭檔裡面。 程式中若使用到 cin 和 cout 物件時要先 含入 iostream.h 標頭檔。 P12-6
下圖是ios、ostream、istream、iostream 類別階層架構,可看出為何用 cin 或 cout物件時,需含入 iostream.h 標頭檔: istream 類別和 ostream 類別繼承 ios 類別,兩者關係,稱 ios類別為「基礎類別」(Based Classs)或「父類別」(Superclass) istream 類別和 ostream 類別稱為「衍生類別」(Derived Class)或稱「子類別」(Subclass)。 P12-7
12-4 C++ 的輸出- 使用 cout 物件 一、如何使用cout物件來輸出資料 P12-9
1. 輸出字串常數 2. 輸出變數(假設int price=15;) 3. 輸出字元 4. 輸出運算式 1. 輸出字串常數 cout << “hello, world “; cout << “hello, world “ <<’\n’; cout << “hello, world “ <<endl; cout << “hello,world” << “\n\n” 2. 輸出變數(假設int price=15;) cout << price; cout << “單價△:△” << price; // △:表示空白 cout << “單價△:”<<price<<” △元”<<’\n’; 3. 輸出字元 cout << ‘y’; 4. 輸出運算式 cout << price*5; P12-11
【範例】 在這個範例使用cout物件輸出字串,整數變數,’\n’ 以及endl換行字元: // FileName : cout1.cpp 01 #include <cstdlib> //含入stdlib.h檔 02 #include <iostream> //使用cout物件必需含入iostream.h檔 03 04 using namespace std; //cout物件定義於std名稱空間下 05 06 int main(int argc, char *argv[]) 07 { 08 long price = 700000; 09 cout << "--- 2008新車上市 ---" ; //輸出字串 10 cout << endl; //endl為換行,也可以改寫成'\n' 11 cout << "馬自達 6代" << '\n'; //直接輸出多個字串 12 cout << "總價" << price << "元\n\n" ; //直接輸出多個字串或變數 13 system("PAUSE"); 14 return EXIT_SUCCESS; //EXIT_SUCCESS為0,表示執行沒有錯誤 15 }
cout 物件輸出原理 cout 物件處理方式是將敘述採由右至左,將插入導向運算子 右邊的資料逐一置入到堆疊中,一直碰到 cout,再將堆疊中 的資料以後進先出(Last in First out)方式,將資料逐一輸出。 以下面cout 敘述 來說明cout物件輸出的原理。
12-5 cout 物件的格式化輸出 C++ 格式化輸出使用cout物件。 cout 常用的幾個成員函式,如width()、precision()、setf()…等,或是格式化 操控子(manipulator)。 上述這些函式及格式化操控字皆被定義在ios類別中。 P12-13
一、格式化輸出 下表是 cout 物件 width、precision、fill 成員函式的 說明,範例都已對整數變數n、字元變數ch做過宣告。 P12-13
P12-14
P12-15 // FileName : cout2.cpp 01 #include <cstdlib> 02 #include <iostream> 04 using namespace std; 06 int main(int argc, char *argv[]) 07 { 08 char ch[]="歡迎光臨"; 09 int n=168; 10 cout.fill('&'); 11 cout.width(10); 12 cout << ch << endl; 14 cout << n << endl; 15 cout.width(5) ; 16 cout << n << endl; 17 cout.fill('%'); 18 cout.precision(5); 19 cout.width(10); 20 cout << 123.45678 << "\n\n"; 22 system("PAUSE"); 23 return EXIT_SUCCESS; 24 } P12-15
二、格式化輸出- cout 物件 setf、unsetf 函式 1. cout.fill('*'); 2. cout.width(8); 3. cout.setf(ios::left, ios::adjustfield); 4. out << "12345" ; 5. cout.unsetf(ios::adjustfield); 6. cout << endl; 7. cout.width(8); 8. cout << "12345" ; P12-16
1. 如何設定輸出的對齊方式 P12-16
P12-17 // FileName : cout3.cpp 01 #include <cstdlib> 02 #include <iostream> 04 using namespace std; 06 int main(int argc, char *argv[]) 07 { 08 cout.fill('#'); 09 cout.setf(ios::left, ios::adjustfield); 10 cout.width(15); 11 cout << "雙城奇謀" << endl << endl; 13 cout.unsetf(ios::adjustfield); 15 cout.setf(ios::right, ios::adjustfield); 16 cout.width(15); 17 cout << "誰與爭鋒" << endl << endl; 18 cout.unsetf(ios::adjustfield); 19 P12-17
20 cout.setf(ios::internal, ios::adjustfield); 21 cout.setf(ios::hex, ios::basefield); 22 cout.setf(ios::showbase); 23 24 cout.fill('*'); 25 cout.width(15); 26 cout << 123456789 << endl; 27 cout.unsetf(ios::adjustfield); 28 cout.unsetf(ios::basefield); 29 cout << "\n"; 30 system("PAUSE"); 31 return EXIT_SUCCESS; 32 }
2. 如何設定八進制及十六進制的輸出 P12-18
P12-19 // FileName : cout4.cpp 01 #include <cstdlib> 02 #include <iostream> 04 using namespace std; 06 int main(int argc, char *argv[]) 07 { 08 cout << "--------- 數字系統 ---------" << endl; 09 cout << "十進制" << 168 << "等於 八進制"; 10 cout.setf(ios::oct, ios::basefield); 11 cout << 168 << endl; 12 cout.unsetf(ios::basefield); 13 14 cout << "十進制" << 168 << "等於十六進制"; 15 cout.setf(ios::hex, ios::basefield); 16 cout << 168 << endl; 17 cout.unsetf(ios::basefield); 19 cout.setf(ios::showbase); P12-19
21 cout << "十進制" << 168 << "等於 八進制"; 22 cout.setf(ios::oct, ios::basefield); 23 cout << 168 << endl; 24 cout.unsetf(ios::basefield); 25 cout << "十進制" << 168 << "等於十六進制"; 26 cout.setf(ios::hex, ios::basefield); 27 cout << 168 << endl; 28 cout.unsetf(ios::basefield); 29 30 cout << "十進制" << 168 << "等於十六進制"; 31 cout.setf(ios::hex, ios::basefield); 32 cout.setf(ios::uppercase); 33 cout << 168 << endl; 34 cout.unsetf(ios::uppercase); 35 cout.unsetf(ios::basefield); 36 37 cout.unsetf(ios::showbase); 38 cout << "\n"; 39 system("PAUSE"); 40 return EXIT_SUCCESS; 41 }
3.如何設定其他的格式化輸出
P12-21 01 #include <cstdlib> 02 #include <iostream> // FileName : cout5.cpp 01 #include <cstdlib> 02 #include <iostream> 04 using namespace std; 06 int main(int argc, char *argv[]) 07 { 08 cout.precision(5); 09 cout << "**浮點數格式化輸出**" << endl; 10 cout << 123.456789 << endl; 11 cout.setf(ios::fixed, ios::floatfield); 12 cout << 123.456789 << endl; 13 cout.setf(ios::scientific, ios::floatfield); 14 cout << 123.456789 << endl << endl; 15 cout.unsetf(ios::floatfield); P12-21
17 cout << "**正負數格式化輸出**" << endl; 19 cout.setf(ios::showpos); 20 cout << 123.456789 << endl; 21 cout << -123.456789 << endl << endl; 22 cout.unsetf(ios::showpos); 23 24 cout << "**布林值格式化輸出**" << endl; 25 bool t=true, f=false; 26 cout << "真為" << t << endl; 27 cout << "假為" << f << endl; 28 cout.setf(ios::boolalpha); 29 cout << "真為" << t << endl; 30 cout << "假為" << f << endl; 31 cout.unsetf(ios::boolalpha); 32 cout << "\n"; 33 system("PAUSE"); 34 return EXIT_SUCCESS; 35 }
三、格式化輸出 - 使用格式化操控子 P12-24
P12-24
P12-25 01 #include <cstdlib> 02 #include <iostream> // FileName : cout6.cpp 01 #include <cstdlib> 02 #include <iostream> 03 #include <iomanip> 04 using namespace std; 06 int main(int argc, char *argv[]) { 08 cout << "------設定對齊方式------" << endl; 09 cout << setfill('#'); 10 cout << setw(10) << left << "C&C++" << endl; 11 cout.setf(ios::adjustfield); 12 cout << setw(10) << "Very Good" << endl << endl; 14 cout << "--十、八、十六進制轉換--" << endl; 15 cout << setfill('\0'); 16 cout << "十進位" << dec << 168 ; 17 cout << "等於 八進位" << oct << 168 << endl; 18 cout << "十進位" << dec << 168 ; 19 cout << "等於十六進位" << hex << 168 << endl; 20 cout << showbase ; 21 cout << "十進位" << dec << 168 ; 22 cout << "等於 八進位" << oct << 168 << endl; 23 cout << "十進位" << dec << 168 ; 24 cout << "等於十六進位" << hex << 168 << endl; 25 cout << noshowbase << endl << endl; 26 system("PAUSE"); 27 return EXIT_SUCCESS; 28 } P12-25
【範例】 使用格式化操控子來測試浮點數、科學記號的輸出。 // FileName : cout7.cpp 01 #include <cstdlib> 02 #include <iostream> 03 #include <iomanip> 04 using namespace std; 05 06 int main(int argc, char *argv[]) 07 { 08 cout << setprecision(5); 09 cout << fixed << 168.789123 << endl; 10 cout << scientific << 168.789123 << endl; 11 cout.setf(ios::floatfield); 12 cout << showbase << 168.789456 << noshowbase << endl << endl; 13 14 system("PAUSE"); 15 return EXIT_SUCCESS; 16 } P12-27
12-6 cerr 物件 cerr 物件主要用來將資料輸出至標準錯誤輸出裝置 此物件由 ostream 類別繼承而來,功能和 cou t物件 類似必須配合「<<」運算子將資料輸出到標準錯誤 輸出裝置。 cerr 和 cout 最大的差異: cout 物件會先將資料存放在 buffer 中接著再輸出 cerr 是直接做輸出,雖使用 cerr 物件會增加I/O的 次數,減低程式效率,但能讓程式設計師在開發除 錯階段即時接收到錯誤的結果。 下面為 cerr 物件的宣告原型: extern ostream cerr; 下面為 cerr 物件的使用寫法: cerr << “這是錯誤 “; P12-28
12-7 clog物件 clog 物件和 cerr物件的功能相同,都是用來將 資料輸出至標準錯誤輸出裝置 此物件是由 ostream 類別繼承而來。 clog 和 cerr 最大的差異是 clog 物件會先將資料存放在buffer中接著再輸出。 cerr 是直接做輸出。 使用clog物件可減少I/O的次數,以增加程式的 效率。 下面為clog物件的宣告原型: extern ostream clog; 下面為cerr物件的使用寫法: clog << “這是錯誤 “; P12-28
12-8 C++ 的輸入- 使用 cin 物件 一、cin物件的使用方式 #include <iostream> using namespace std; P12-29
P12-29 【例1】以下簡例用來取得由鍵盤輸入的整數變數資料,並 指定給age變數。 1. int age; 2. cout << "請輸入你的年齡" ; 3. cin >> age ; // 此時輸入的整數會指定給變數age 4. cout << "\n你" << age << "歲"; 【例2】以下簡例可由鍵盤連續輸入三個整數,然後依序指定 給chi、eng、math變數。 1. int chi, eng, math; 2. cout << "請輸入國文、英文、數學的成績" ; 3. cin >> chi >> eng >> math ; 4. cout << "\n國文" << chi << "分"; 5. cout << "\n英文" << eng << "分"; 6. cout << "\n數學" << math << "分"; P12-29
【例3】由鍵盤輸入包含10個字元的字串,然後依序 指定給 name 字元陣列變數。 1. char name[10] ; 2. cout << "輸入姓名" ; 3. cin >> name ; 4. cout << "Hello!!" << name ;
P12-30 06 int main(int argc, char *argv[]) { 08 int y, m, d; // FileName : cin1.cpp 06 int main(int argc, char *argv[]) { 08 int y, m, d; 09 cout << "請輸入考試日期-->" ; 10 cin >> y >> m >> d; 11 cout << "你輸入的日期是-->" << y << "/" << m << "/" << d << endl << endl; 13 int ans ; 14 cout << "請問電影哈利波特中的黑魔王是誰?" << endl; 15 cout << "1.佛地魔 2.榮 恩 3.天狼星" << endl; 16 cout << "請輸入答案-->" ; 17 cin >> ans; 18 if (ans==1) { 20 cout << "好棒!!答對了!!" ; 21 } 22 Else { 24 cout << "再加油!!答錯了!!" ; 25 } 26 cout << "\n\n"; 27 system("PAUSE"); 28 return EXIT_SUCCESS; 29 } P12-30
P12-31
// FileName : cin2.cpp 01 #include <cstdlib> 02 #include <iostream> 03 #include <iomanip> 04 using namespace std; 05 06 int main(int argc, char *argv[]) 07 { 08 char name[15] ; 09 float chi, eng, math, avg; 10 cout << "姓名:"; 11 cin >> name; 12 cout << "國文:"; 13 cin >> chi; 14 cout << "英文:"; 15 cin >> eng ; 16 cout << "數學:"; 17 cin >> math ; 18 avg=(chi+eng+math)/3; 19 cout << endl << name << "," << "平均分數為" << setprecision(2);
20 cout.setf(ios::fixed, ios::floatfield); 21 cout << avg ; 22 cout.setf(ios::floatfield); 23 if(avg>=90){ 24 cout << ",成績優等!!"; 25 }else if(avg<90 && avg >=80){ 26 cout << ",成績甲等!!"; 27 }else if(avg<80 && avg >=70){ 28 cout << ",成績乙等!!"; 29 }else if(avg<70 && avg >=60){ 30 cout << ",成績丁等!!"; 31 }else if(avg<=59){ 32 cout << ",重考!!"; 33 } 34 cout << "\n\n"; 35 system("PAUSE"); 36 return EXIT_SUCCESS; 37 }
二、cin.getline 方法 若在cin2.cpp範例的姓名中輸入 ”Peter Lee” ,會得到不可預期的輸出情形。
二、cin.getline 方法 允許由鍵盤連續鍵入的任何字元,一直到按<Enter> 鍵為止,此時系統自動在所讀取一系列字串後面 加上字串結束字元(\0空字串),形成一個字串, 再將此字串放入指定的字元陣列中。 cin.getline方法的語法說明如下:
【範例】延續上例,使用cin物件的getline方法來 解決上一個範例的問題。 // FileName : cin3.cpp 06 int main(int argc, char *argv[]) { 08 char name[15] ; 09 float chi, eng, math, avg; 10 cout << "姓名:"; 11 cin.getline(name, 15); 12 cout << "國文:"; 13 cin >> chi; 14 cout << "英文:"; 15 cin >> eng ; 16 cout << "數學:"; 17 cin >> math ; 18 avg=(chi+eng+math)/3; 19 cout << endl << name << "," << "平均分數為" << setprecision(2); 20 cout.setf(ios::fixed, ios::floatfield); 21 cout << avg ; 22 cout.setf(ios::floatfield); P12-34
23 if(avg>=90) { 24 cout << "成績優等!!"; 25 } else if(avg<90 && avg >=80){ 26 cout << "成績甲等!!"; 27 } else if(avg<80 && avg >=70){ 28 cout << "成績乙等!!"; 29 } else if(avg<70 && avg >=60){ 30 cout << "成績丁等!!"; 31 } else if(avg<=59){ 32 cout << "重考!!"; 33 } 34 cout << "\n\n"; 35 system("PAUSE"); 36 return EXIT_SUCCESS; 37 }
本章結束 Take a break ….