在上一篇文章中,我們學會了如何建立程式碼檔案、以及從程式碼變成執行檔的方法; 而這一篇要教大家如何在終端機上輸出文字。
對於輸出文字,我們需要用到printf的功能,細心的人應該會注意到我們在上一篇已經偷用過一次了! 我想對於新人來說,printf完整的用法可能太複雜,所以我並不打算在這裡把它全部教完,而是用到某個功能的時候才交代某個功能的用法。 如果你迫不及待想要知道printf完整的用法,可以去C++ Reference (http://www.cplusplus.com/reference/cstdio/printf/)網站參考。
另外要提醒一件很重要的事,C語言是會區分大小寫的語言,比如說printf和Printf和PRINTF都是不一樣的東西。 也就是說如果我叫你寫printf而你寫成Printf的話,編譯器是會看不懂的! 因此請注意我教學和範例上的大小寫,勿隨意的變更大小寫。
在使用printf之前
首先,當你的程式碼需要使用到printf功能的時候,必須在程式碼的最開頭地方加上#include <stdio.h>的敘述:
#include <stdio.h> int main(int argc, char *argv[]) { return 0; }
現在還不知道詳細的原因和原理沒關係,有關#include的敘述我們會在以後進入「多檔案編譯」有關章節的時候說明, 你現在只要記得「當有使用到printf的時候,就要在程式碼檔案開頭加上#include <stdio.h>」這樣就可以了! 還有,一般我們習慣會多加空行把#include的敘述和下面的程式碼做出區隔。
印出普通的文字
printf最簡單的使用方式是像下面這樣:
printf(這裡放入要輸入的文字);
即在printf後面加上小括弧,然後把要顯示的文字放在裡面。 但為了防止編譯器搞不清楚你寫的東西是個指令還是只是單純的文字,因此C語言規定所有的「文字串」都必須以雙引號「"」包裹。 拿上一篇的程式做為範例,若我想要印出「First program!」則應該寫成:
printf("First program!");
然後請記得,整個敘述完成後要在最後面加上一個分號「;」告訴編譯器說這個敘述到這裡結束了,這是C語言的規定。 最後,完整的程式碼會變成這樣:
#include <stdio.h> int main(int argc, char *argv[]) { printf("First program!"); return 0; }
印出文字的限制
列印文字看起來很簡單,可是其實還有一些限制,有一些符號具有特殊用途,所以不能直接的寫在輸出文字裡:
- 「"」:雙引號被用來包裹文字串,所以如果在文字串中也出現雙引號的話,會讓編譯器搞不清楚字串的範圍。
- 「\」:反斜線在字串裡面被C語言用來表示一些「打不出來」的符號, 如果你的字串裡面有出現反斜線的話,你應該會發現除了反斜線顯示不出來外,整個文字的顯示也會有點怪怪的! 有關反斜線的用法我們稍候就會提到。
- 「%」:這裡先澄清一下,其實百分比符號是允許出現在字串裡面的,只不過printf這個功能對百分比符號還有特別的安排。
- 中文:這裡的中文其實是指英文以外的其他語言文字, 其實字串裡面並非不能輸入非英文,只是我覺得這個議題實在是太進階了! 除非你已經完全了解有關字元編碼的知識,否則請不要貿然的在字串裡面輸入英文以外的其他語言文字, 否則以後遇到什麼鬼打牆、想半天找不到原因的問題時可別怪我沒警告過你!
跳脫字元
printf幾乎可以印出任何你輸入的文字,除了上面提到不可輸入的文字、以及一些打不出來的文字。 於是一個問題產生了,如果要印出一些打不出來的東西怎麼辦呢?比方說換行? 於是C語言特別為了這些需求,把反斜線「\」用來標示這些特殊符號、格式。
當字串中出現反斜線,就是在告訴編譯器說:「注意喔,反斜線的下一個字是特殊功能,不是普通的文字喔!」 因此反斜線後面再搭配一個(大部份是一個,幾個特殊的有用到多個的)我們打的出來的文字來表示一些特殊格式, 比方說「\n」就是「換行」。 你可以試試用printf寫成這樣:
printf("First\nprogram\n!\n");
執行後,終端機應該會印出:
First program !
這也就是為我們一般在使用printf的時候都會在字串後部加上一個「\n」的關係, 這是因為通常在文字輸出完了後我們會想要換下一行,不然下一次的輸出會直接接在這一次輸出的後面。
由於像\n這樣的東西不會被直接顯示出來,而是會產生其他的效果,於是我們就稱呼這種東西叫「Escape Characters」, 中文翻譯叫「溢出字元」、「逃脫字元」、或「跳脫字元」,當中並沒有哪一個是最正確的,但我習慣叫它跳脫字元。 既然反斜線被用來表示跳脫字元,那如果我們就是要顯示反斜線的話怎麼辦呢? 這時就會用到另外一個跳脫字元「\\」,意思就是告訴編譯器「這就是一個普通的反斜線」。
當然,跳脫字元不是只有換行和反斜線而已,還有其他的跳脫字元列表於下:
跳脫字元 | 意義 | 字碼號(HEX) | 備註 |
---|---|---|---|
\a | 響鈴(BEL) | 07 | |
\b | 退格(BS) | 08 | |
\t | 水平定位符號(HT) | 09 | |
\n | 換行(LF) | 0A | |
\v | 垂直定位符號(VT) | 0B | |
\f | 換頁(FF) | 0C | |
\r | 輸入(CR) | 0D | |
\\ | 反斜線 | 5C | |
\0 | 空字符號(NUL) | 00 | |
\" | 雙引號 | 22 | |
\' | 單引號 | 27 | |
\? | 問號 | 3F | |
\x## | 直接指定一個位元組的值 | ## | ##為兩個十六進位的數字 |
\### | 直接指定一個位元組的值 | ### (in octal) | ###為三個八進位的數字 |
\u##... | 直接指定一個UTF-8格式文字的內碼號 | ##...為數個十六進位的數字 (建議不要使用這個功能,因為語意不明確) |
|
\U##... | 直接指定一個UTF-16格式文字的內碼號 | ##...為數個十六進位的數字 (建議不要使用這個功能,因為語意不明確) |
我想對於新手來說,上面的表格裡因該有很多東西是看不懂的吧! 不過其實沒關係,你只要需要用的時候知道去查這些東西就可以了。 基本上平常會比較常用到的也只有「\n」、「\"」、「\\」、和「\x##」這四個而已, 其中關於十六進位碼的部份若不清楚的話可以先忽略且不使用它們。
printf格式字元
除了所有用雙引號包裹起來的字串都會依尋上面提到的跳脫字元標準以外,printf因為本身的需要也使用了一些「格式化字元」, 而這些格式化字元使用百分比符號「%」做為開頭,這也是為什麼printf不能直接顯示百分比符號的關係。 然而百分比符號只有在使用printf之類函式時才需要做特別處置,至於在其他的地方使用上則完全沒有限制, 因為這些格式符號只會被printf類的功能所解析處理。
我想printf的格式字元對於初入門者來說實在是太複雜了!所以我只會在我們應用到的時候才提它的某一個部份。 以目前來說,你只需要知道當你想要印出一個百分比符號時應該要寫成「%%」(與\\有點類似)就可以了!
標準輸出輸入
這裡再補充一個知識,我們常說printf這類的功能是把文字印到螢幕上、scanf之類的功能則是從鍵盤接收使用者的輸入, 然而這其實是口語化的說法,嚴格來說並不完全正確。 正確來說,printf這類的功能是將文字印出到「標準輸出裝置」上;而scanf這類的功能是從「標準輸入裝置」截收文字。 不同在於標準輸出輸入裝置通常是但不一定是螢幕和鍵盤,基本上我們還可以使用資料流重導向的技巧把它導引到其他地方,比方說一個檔案。
重點回顧
- C語言是區分大小寫的程式語言,請注意有關大小寫的問題。
- 使用printf("text");的寫法可以在終端機上印出文字。
- 如果程式有使用到printf的功能,則應該在程式碼最開頭加上#include <stdio.h>的一行敘述。
- 文字串裡並不是什麼字都可以直接打上去,請注意有關跳脫字元以及格式字元的部份。
- 請不要在字串裡寫上包含中文等非英文文字,除非你已經對於字元編碼的相關知識非常有把握了!
- printf其實是將文字往標準輸出裝置送,而這個裝置不一定是終端機螢幕。
練習與討論
請試著用你到現在所學到的知識寫一個程式,使用一個printf把下面這篇短文一字不差的顯示在終端機上:
I am learning the "C" programming language. It is not so easy... (%_%) But I am studying very hard, and I will make something really cool! \(^^\)