char
是C/C++的基本資料型態,大小為一個位元組 (1 byte),可以儲存單一個字元。
例如,宣告一個字元型態變數ch
,值為字母 A,寫法如下:
C++使用一對單引號''
,將一個字元括起來,代表他的 ASCII 碼。
我們可以宣告字元變數,搭配使用cin
,嘗試從鍵盤讀入一個字元:
注意cin
會跳過換行、空白、tab等空字元,只讀取一個字母。因此,若輸入為:a b
,以上程式將只會輸出字母 a 。
ASCII code 全名為「American Standard Code for Information Interchange」,是一套依據拉丁字母的電腦編碼系統。在電腦中,所有的資料在儲存和運算時都要使用二進位數表示。而具體用哪些二進位數字表示哪個符號,這就是編碼。如果不同的電腦要想互相通信而不造成混亂,那麼每台電腦就必須使用相同的編碼規則,於是美國有關的標準化組織就推出了ASCII編碼。
字元最大的用處,就是以 ASCII 碼的形式,將文字資訊顯示出來。基本 ASCII code 對照表如下。數字 0~127 ,分別對應到大、小寫英文字母、阿拉伯數字、一些半形標點符號,還有一些控制字元。
我們可以將ASCII碼,設定給字元變數。例如,將字元 A 設定給字元變數 ch,以下寫法有相同的效果:
程式將 ASCII 碼指定給char
型態的變數,因此若接續以cout
輸出,會顯示字母 A,而非整數 65。
當我們想要表達的文字超過一個字母時,就必須使用 「字串」。在C++語言中,有兩種儲存字串的方式,均須使用雙引號""
將所需字串括起來:
1) 以字元陣列(char array
)來宣告字串:
在上面這個例子,記憶體會使用連續的 6 個位元組來記錄字串"HAPPY"
,參考課本3-5。最後一個字元為 '\0'
,代表字串的結束。這種用法同時適用於C語言,但使用方法比較繁瑣,課堂上就不說明了,有興趣的孩子可以閱讀課本相關章節,或是參考這篇教學文章。
2) 以string
類別宣告字串:
string
是一個保存 char
的類別物件,是一個長度可變動之字元序列,減輕了 C 語言風格字串的麻煩。如需使用string
,必須引入標頭檔string
。
現在,我們來寫一個程式,使用者輸入什麼字,程式就吐出什麼字:
範例輸入 | 範例輸出 |
---|---|
Hello |
Hello |
從以上程式可以發現,在main
函式之前要加上一行#include <string>
,引入標頭檔string
,否則編譯可能會發生錯誤。
請注意,如果讀取字串遇到空白,換行等空字元就會斷開,無法讀取整行。我們可以使用以下程式,將單字一個、一個讀取,作出相應行為,例如一個一個輸出:
範例輸入 | 範例輸出 |
---|---|
Tony Stark |
Tony Stark |
然而在某些狀況下,我們會需要一次讀取一整行輸入,此時就必須搭配使用getline()
函式,請參考課本 3-5 的說明。
A. 建議使用string
。接著請在課本中尋找,用什麼函式能取出字串長度,作為for
迴圈的終止條件?在迴圈之中,又如何表示字串內的每個字元?
char
轉成int
型態?A. 以下舉例說明,如何將數字 123 的每個位數依序顯示出來,中間以空白間隔。
【錯誤方法】
以上程式直接使用int
進行型別轉換,然而轉換後的結果依序為數字 1, 2, 3 的ASCII碼,並非其真正的數值。
【法一】扣掉 0 的 ASCII code
已知數字 0 的 ASCII code 為 48 ,那麼將每個數字字元轉換成 ASCII 碼之後,每個都扣掉 48,就是原始數值了。
【法二】直接扣掉 '0'
如果忘記數字 0 的 ASCII 碼,那有什麼關係!我們其實可以把兩個字元直接做加減,計算他們的「距離」。
上面的程式碼微調如下,計算字元s[i]
與字元0
的 ASCII 碼相差多少,同樣能夠依序顯示 1, 2, 3。
for
迴圈,將每一回合得到的數字加起來?A. 宣告總和變數,累加計算結果,上禮拜應該有稍微複習到。以下舉例說明,如何計算數字 1 ~ 10 的總和。
因為本題要分別計算奇位數字和和偶位數字和,會需要兩個總和變數。因此,你需要在for
迴圈中,判斷該位數是奇位數字還是偶位數字,累加到相應的總和變數。
取決於使用for
迴圈檢查字元的順序。如果你從字串第 0 位,也就是最高位開始檢查,它可能是奇位數字或偶位數字,需要用字串長度判斷是哪一種。如果你從字串最後一位開始檢查(小心迴圈起始條件),那它一定會是奇位數字。程式架構如下:
A. 當然!我們可以使用內建的字元轉換函式,將傳進來的字元參數由小寫轉大寫,或是由大寫轉小寫。
使用tolower()
,可將括弧內的字元轉成小寫字母。注意如果參數不是字母,或已經是小寫字母,就不會有任何變化。
使用toupper()
,則可將括弧內的字元轉成大寫字母。參考範例:
A. 有兩種方法:內建函式法與ASCII 距離判斷法。
常見的幾種字元分類函式如下:
函式名稱 | 說明 |
---|---|
isalpha |
判斷是否為英文字母 |
islower |
判斷是否為小寫字母 |
isupper |
判斷是否為大寫字母 |
isdigit |
判斷是否為數字 |
isalnum |
判斷是否為英文字母或數字 |
左方函式都有個共同特性:若符合條件,則回傳一非零整數。若不符合條件,則回傳 0 。
至於這些函式該如何使用呢?練習用關鍵字找答案,自己去google吧!答案都在那裡了!
如果忘記或懶得查詢內建函式怎麼用,以下為萬用方法。
我們從ASCII code table可以發現,0 到 9、A 到 Z、a 到 z,其 ASCII code都是連續的。因此,我們可以將兩個 ASCII code 直接相減,以差值判斷未知字元是哪一種字元。
請注意,以上程式適用的情況有限。像是輸入為 0 - 9,扣掉字母 A 的 ASCII code,結果為負數,在這個程式就會被誤判為大寫字母。
getline()
讀取一整行輸入字串。A. 舉例如下:
A. 我們先來解一個比較簡單的小任務:如何寫一個程式,將ABCDEFGHIJKLMNOPQRSTUVWXYZ
往後平移 3 ,變成DEFGHIJKLMNOPQRSTUVWXYZABC
?顯然,把 X, Y, Z變成 A, B, C,是解題的關鍵。我們就可以區分兩個子問題:
如何判斷 ASCII code 會加到超過 Z?(想出判斷式)
如何回到 A 之後,繼續加上沒加完的平移量?(想出四則運算式)
提示是上一題可以使用的 ASCII 距離判斷法,你可以運用加號和減號,直接將 s[i]
與 單一字元做運算。例如:s[i] - ‘A’
,用以計算字串 s 的第 i 個字元,其 ASCII code 比字元A
多多少。
以下程式有兩個地方打上???
,請思考這兩個地方分別要填什麼,嘗試完成這個小任務。
這個小任務可以有好幾種做法。例如,有些人可能想要先將 ASCII code 平移到 0 ,再運用取商跟取餘數運算子,除以 26 進行一些運算,就不需判斷 ASCII code 相加有無超過,這樣也很好!
cin
每一行字串嗎?A. 觀察輸入說明及範例輸入,一長串連續的位元中,是否可能出現空格呢?如果保證每一行無空格,才能使用cin
,否則就需要使用getline()
函式來處理輸入。
A. 宣告一整數或布林型態的變數,再進入迴圈檢查。當遇到不是 0 或 1 的字元,要做什麼事情?當然,你也可以自定義一個函式(之後也會教),以回傳值代表是否為合理的2進制位元串。
A. 需要先了解何謂二進位制,可以google一下。簡單來說,幾個位元就能夠表示 2 的幾次方個數字。從 0 開始的話, 個位元最大可以表示的數字為 。因此,重複位元的長度用 3 個位元,最大連續長度為 。
A. 觀察範例測資中,前兩組測試資料。連續長度若超過 7,即使位元與前面相同,仍須重新統計,以下一組4位元碼字來表示。
A. 你可以使用:
先求有再求好!因為重複字元很少,也就 7 種可能,可以使用選擇結構,根據重複次數輸出相應結果。
上網搜尋 10 進位轉 2 進位的方式,發現規律後,嘗試以while
迴圈搭配字串組合來完成任務。