View
222
Download
3
Embed Size (px)
Citation preview
Chapter 11
Strings and Vectors
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 2
Overview
• An Array Type for Strings (11.1)• The Standard string class (11.2)• Vectors(11.3)
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 3
11.1An Array Type for Strings
• C-strings 用來表示字元串接成的字串• C-strings 被儲存成字元陣列• C-strings 以 虛字元 ‘ \0’ 來結束字串
• 虛字元 ‘ \0’ 為一特殊字元• 宣告 C-strings 的語法:
char s[11];
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 4
s[0] s[1] s[2] s[3] s[4] s[5] s[6] s[7] s[8] s[9]
H i M o m ! \0 ? ?
C-string Details
• 如 char s[10] 的 C-string 宣告, 會產生一個能放入 9 個字元的記憶體空間• 保留一個字元的空間來放結束字串的虛字元 ‘ \0’
• 一個 C-string 變數不需要另外的變數來表示其含有多少個字元 ( 就是大小 )• 虛字元緊接在字串的最後一個字元
• 範例:•
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 5
C-string Declaration
• 宣告 C-string 變數的語法 :
char Array_name[ Maximum_C_String_Size + 1];
• + 1 保留了放置 ‘ \0‘ 所需的一個字元的記憶體空間
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 6
Initializing a C-string
• 在宣告時就給初始值 : char my_message[20] = "Hi there.";• 系統會自動於最後補上虛字元 ‘ \0’
• 另一種方式 : char short_string[ ] = “abc”; 但以下字元陣列不能代表字串 : char short_string[ ] = {'a', 'b', 'c'}; • 上面的錯誤是因為在給字元陣列初始值時,系統不會自
動補上虛字元 ‘ \0’
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 7
Don't Change '\0'
• 運用 C-string 中的索引時,不要隨意將虛字元( the null character) 取代掉• 如果虛字元不見了,該字元陣列就不能表現出字串的相
關操作Example: int index = 0;
while (our_string[index] != '\0') { our_string[index] = 'X'; index++; }
• 上面這個迴圈範例要靠找到字串的結束虛字元 (the null character!)
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 8
Safer Processing of C-strings
• 上面這個迴圈範例要靠找到字串的結束虛字元 (the null character!) ,萬一虛字元 ‘ \0’ 已被換掉的話,上面的程式碼將無法控制,為避免上述情況,最好改用下面這個程式碼 int index = 0;
while (our_string[index] != '\0‘ && index < SIZE) { our_string[index] = 'X'; index++; }
// 限制索引有效範圍不能超過 SIZE
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 9
Assignment With C-strings
• 以下這列程式碼不合語法 :
a_string = "Hello";• 這是一個將右方值指定給左方變數的程式碼,而不是宣
告時給的初始值• 這種指定的運算子不能適用於 C-strings
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 10
Assignment of C-strings
• 指定一個字串給 C-string 變數要使用 定義於 cstring 函式庫的 strcpy 函式• Example: #include <cstring>
… char a_string[ 11];
strcpy (a_string, “Hello”);
- 將 “ Hello” 及其後的一個 null character 複製到 a_string 字元陣列中
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 11
A Problem With strcpy
• 使用 strcpy 時要注意• strcpy 並未檢查第一個字元陣列參數的長度• 因此第 2 個參數的長度有可能會超過第 1 個參數的陣
列大小,覆蓋掉該陣列之後的記憶體的內容,造成程式當機
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 12
A Solution for strcpy
• strncpy 是比較安全的 strcpy• strncpy 使用第 3 個參數來限定最多會複製的字元數目• Example: char another_string[10];
strncpy(another_string, a_string_variable, 9);
這個程式碼最多複製 9 個字元到 another_string ,留下一個字元空間給 '\0'
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 13
== Alternative for C-strings
• = = 運算子也不能用來檢查兩個 C-string 是否相等• 必須改用 strcmp 來比較兩個 C-string 變數• Example: #include <cstring>
… if (strcmp(c_string1, c_string2)) cout << "Strings are not the same."; else cout << "String are the same.";
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 14
strcmp's logic
• strcmp 由左至右比較兩參數之數字碼大小 ( 依據 ASCII 碼 )• 如果兩邊相等 , strcmp returns 0
• 0 在 C++ 會被解析為 false
• 只要找到不相等之對應字元• 如果第 1 個參數的值較小, strcmp returns 負值 • 如果第 1 個參數的值較大, strcmp returns 正值• 非 0 (Non-zero) 之值在 C++ 會被解析為 true
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 15
More C-string Functions
• cstring 函式庫包括以下常用函式:• strlen 傳回 C-string 參數的字元數
int x = strlen( a_string);• strcat 串接兩個 C-strings
• 第 2 個參數加到第 1 個參數之後• 得到的 C-string 放在第 1 個參數• Example:
char string_var[20] = “The rain”; strcat(string_var, “in Spain”);
string_var 的 C-string 為 "The rainin Spain"
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 16
Display 11.1 (1)
Display 11.1 (2)
The strncat Function
• strncat 是 strcat 的安全版本• 第 3 個參數會限定最多可以新增的字元數• Example:• char string_var[20] = "The rain";
strncat(string_var, "in Spain", 11);
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 17
C-strings as Arguments and Parameters
• C-string 變數都是陣列• C-string 用於函式的定義及呼叫的方式與陣列相同
• 如果函式會改變 C-string 參數的內容,最好多加上一個表示該 C-string 大小的參數,以策安全
• 如果函式會改變 C-string 參數的內容, 可以檢查 the null character (‘\0’) 來決定 C-string 是否已結束,因此不需要多加上一個表示該 C-string 大小的參數
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 18
C-string Output
• C-strings 可以用 << 輸出• Example: char news[ ] = "C-strings";
cout << news << " Wow." << endl;
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 19
C-string Input
• >> 可以輸入 C-string 變數的值• 遇到 Whitespace ( 如 ‘ ‘ , ‘\n’, ‘\t’) 會結束 C-string 的
讀取 • Example: char a[80], b[80];
cout << “Enter input: ” << endl; cin >> a >> b; cout << a << b << “End of Output”;使用者介面顯示如下 : Enter input: Do be do to you! DobeEnd of Output
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 20
Reading an Entire Line
• getline 可以讀入一整列文字,包括 ‘ ‘ 及 ‘ \t’• getline 是 all input streams 的一個成員函式,可用於
命令提示字元視窗或檔案輸入• getline 有兩個參數
• 第一個參數是 C-string 變數,用來放置讀入的一整列文字 ( 不包括 ‘ \n’ )
• 第一個參數是一個整數,通常就是第 1 個參數的陣列大小,用來指定這一列文字最多能填入第一個參數的字元數目
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 21
Using getline
• 讀入一整列的範例• char a[80];
cout << "Enter input:\n";cin.getline(a, 80);cout << a << End Of Output\n";
使用者介面顯示如下 : Enter some input: Do be do to you! Do be do to you!End of Output
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 22
getline wrap up
• 當讀入的字元數達到 第 2 個參數的值 -1 , getline 會停止讀取字元的動作
• 一個字元的空間要保留給 the null character (‘\0’)• 即使還沒讀到此列最後, getline 也會不再讀取後續的
字元
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 23
getline and Files
• C-string 輸入 (>>) 及輸出 (<<) 同樣適用於檔案• 只要將 cin 換成輸入檔案的字串流即可
in_stream >> c_string; in_stream.getline(c_string, 80);
• 只要將 cout 換成輸出檔案的字串流即可 out_stream << c_string;
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 24
getline syntax
• getline 與語法如下
cin.getline(CString_Var, Max_Characters + 1);
• cin 可換成輸入檔案的字串流• Max_Characters + 1 保留一個字元記憶體空間給 the
null character(‘\0’)
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 25
C-String to Numbers
• “1234” 是一個字串• 1234 是一個數字• 當進行數字的輸入時 , 有時可以先將字元以 C-
String 的方式讀入 , 再將該字串轉成數字• 例如讀入金額時可以先處理掉 ‘ $’ 字元 • 讀入百分比時可以先處理掉 ‘ %’ 字元
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 26
C-strings to Integers
• 如何將 integer 以字元的方式讀入• 將字元放到 C-string , 將不需要的字元移除• 使用預設函式 atoi 將 C-string 轉成一個 int 的值
• Example: atoi("1234") returns the integer 1234 atoi("#123") returns 0 because # is not a digit
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 27
C-string to long
• 大一點的整數可使用 atol 來轉換
• atol 傳回值的資料型態是 long
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 28
C-string to double
• 使用 atof 可以將 C-strings 轉換成 double 資料型態• Example: atof("9.99") returns 9.99
atof("$9.99") returns 0.0 because the $ is not a digit
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 29
Library cstdlib
• 這些轉換函式 atoi atol
atof都在 cstdlib 函式庫
• 要使用時需
#include <cstdlib>
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 30
Display 11.2 (1)
Display 11.2 (2)
Numeric Input
• 知道如何將 C-String 轉成數字後• 如何讀入字元 ?
• 在 Display 11.2 中, read_and_clean 函式會• 讀入一整列字元• 捨棄不是 ‘ 0’ 到 ‘ 9‘ 的字元• 使用 atoi 將整理過的 C-string 轉成 int
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 31
Display 11.3 (1)
Display 11.3 (2)
Confirming Input
• 在 Display 11.3 , get_int 函式會• 使用 read_and_clean 讀入輸入字元• 允許使用者重複輸入,一直到滿意 read_and_clean 轉
出的數字為止
Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 32
Section 11.1 Conclusion
• Can you• Describe the benefits of reading numeric data as
characters before converting the characters to a number?
• Write code to do input and output with C-strings?• Use the atoi, atol, and atof functions?• Identify the character that ends a C-string?