為什麼這篇Printf s鄉民發文收入到精華區:因為在Printf s這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者LPH66 (f0VMRgEBA)看板C_and_CPP標題Re: [問題] scanf、pri...
首先一個觀念:
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