Re: [問題] scanf、printf、%s、%c的問題

看板C_and_CPP作者 (f0VMRgEBA)時間12年前 (2013/05/22 20:31), 編輯推噓5(501)
留言6則, 6人參與, 最新討論串2/2 (看更多)
首先一個觀念: scanf/printf 在使用時你必須把你的格式字串跟參數做一一對應 如果沒有對應的話得到的結果會是奇怪的東西 (至於是什麼奇怪的東西或是為什麼是這些奇怪的東西 這不是一個初學者需要知道的問題 雖然個人覺得這種問題除非是要寫 compiler 不然也不需要知道就是了 如果真有心想要研究的話可以參考我的 #1A00M619 那篇回的人的問題也是沒有正確對應造成的) 至於對應的方法 printf 的情形比較單純 %s 需要一個字串 (或者該說是 char *) %c 則需要一個 char scanf 則稍微不太一樣 一般來說 scanf 需要的是指向目標的指標 (例如 %c 需要一個 char *) (所以在初學時會跟你講 scanf 要讀進那個變數要加 & 就是因為它需要那個變數的指標 所以需要一個 & 取址) 但是 %s 例外 它需要的是目標字串本身那個指標 而不是指向那個字串的指標 所以 %s 也是需要一個 char * 但是它跟 %c 的 char * 意義是不同的 (這也就是為什麼 %s 平常在用時不加 & 的原因) 那麼以下來解釋一下你的四種狀況: ※ 引述《Parisienne (Parisienne)》之銘言: : 看到字串的輸入輸想到一些問題,很混淆,想釐清觀念,麻煩大家了,謝謝。 : #include <stdio.h> : #include <stdlib.h> : int main(int argc, char *argv[]) : { : char str[6]; : printf("輸入: "); : scanf("%s", str); //(a) : printf("%s\n", str); //(b) : int i; : for(i = 0; i < 6; i++) : printf("%c", str[i]); //(c) : system("PAUSE"); : return 0; : } : 1. (a)用%s,表示input為字串,(b)用%s,表示以字串形式輸出,(這樣的理解正確嗎?) : 若輸入hello,則(b)(c)都可得到hello 這個是標準使用方法無誤 所以你這一點的理解是正確的 : 2. (a)用%s,表示input為字串,若(b)用%c代表什麼意思? 輸入的字串用字元形式輸出? : 輸入hello,則(b)(c)的結果如 http://imgur.com/f5WcasS
: 不懂為何(b)的輸出結果為該圖形... 這裡你用了 %c 來印一個 char * 這是不正確的對應 所以會輸出奇怪的東西 這邊你不需要理解為何會有這種輸出 只要知道這樣寫是錯的就行了 : 3. (a)用%c,表示input為單一字元? 還是字元陣列? 若(b)用%c : 輸入hello,則(b)(c)的結果如 http://imgur.com/Kavy1eL
: 不懂(b)(c)的輸出結果... 這裡就是我說的意義不一樣的地方了 首先 一個陣列的名字可以代表它的第一個元素的位址 也就是說 在你的程式裡 str 跟 &str[0] 是一樣的意思 所以這裡的 scanf 其實是 scanf("%c",&str[0]); 那這就是讀入一個字元到 str[0] 裡面 於是這麼一來 str 這個陣列裡的其他元素由於沒有初始化過 其值是垃圾 (參照置底十三誡之一) (c) 的輸出可以看出這一點 除了第一個字 (str[0]) 是讀進來的 h 之外 其他都是垃圾值 (b) 的部份則跟 2. 一樣 你可以不必理解這些奇怪的東西 : 4. (a)用%c,若(b)用%s,輸入hello,則(b)(c)的結果如 http://imgur.com/galUzPa
: 不懂(b)(c)的輸出結果... (c) 的部份跟 3. 一樣就不贅述 (b) 這裡則又是一個重點 在 C 語言裡 一個字串會一直延伸到看到第一個 '\0' 的時候才結束 平常的字串 (例如 "hello" 或是用 scanf 讀進來的字串) 都會自動加上這個 '\0' 所以並沒有問題 但是這裡 str 陣列裡的後五個元素是垃圾值 printf 並不會知道那個其實是垃圾值 它會單純的一直印字元到看到 '\0' 為止 幸好你這次的輸出當中在陣列裡有 '\0' 的存在 所以就只印到那裡為止 (證據是 (c) 的輸出中對於 str[5] 印出了 ')' 但前一行並沒有出現 這表示由於前面出現了 '\0' 所以停住了而已) 不然的話由於 printf 並不會自動停在 str 陣列的範圍裡而會繼續走下去印字 這可能會造成存取到其他不該存取的地方而使程式當掉 (aka.「本程式即將關閉」) (這一點可參照置底十三誡之二) -- 有人喜歡邊玩遊戲上逼; 也有人喜歡邊聽歌打字。 但是,我有個請求, 選字的時候請專心好嗎? -- 改編自「古 火田 任三郎」之開場白 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.118.121.182

05/22 20:39, , 1F
推lph
05/22 20:39, 1F

05/22 20:57, , 2F
05/22 20:57, 2F

05/23 04:09, , 3F
推!!
05/23 04:09, 3F

05/25 20:49, , 4F
感謝前輩的回答!! 大概有些了解了
05/25 20:49, 4F

05/28 20:06, , 5F
真詳細!!
05/28 20:06, 5F

10/26 14:22, , 6F
謝謝
10/26 14:22, 6F
文章代碼(AID): #1HdBgkB7 (C_and_CPP)
文章代碼(AID): #1HdBgkB7 (C_and_CPP)