2010-03-13 39 views
3

當我編譯scanf("%s", &var);,GCC發送回一個警告:使用在scanf符號()

warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’ 

然而當我編譯scanf("%s", var);,沒有施加警告。代碼工作和我正在閱讀的書都特別說明了使用&符號,但即使它並不在某些示例中。

我的問題是,即使書中沒有指定,我是否應該繼續使用&符號?

+3

直到你知道什麼是指針,如果它是'%s',不要使用'&',否則總是使用它。 (Duplicate?http://stackoverflow.com/questions/2062648/c-scanf-question) – kennytm 2010-03-13 19:38:25

回答

4

從你發佈的內容var是一個字符數組。在這種情況下,您不需要&符號,只需要名稱var將根據需要計算爲(char *)。

詳細說明:

scanf的需要一個指向將存儲輸入變量。在字符串的情況下,需要一個指向內存中字符數組的大小的指針,以存儲所讀取的任何字符串。當您聲明類似char var[100]的東西時,將使用var [0]指向100 char s的空間第一個字符和var [99]指的是第100個字符。數組名稱本身的計算結果與&var[0]的計算結果完全相同,它是指向序列第一個字符的指針,正是scanf所需的。所以你需要做的只是scanf("%s", var);,但是請注意scanf不會對輸入字符串實施大小限制,所以如果用戶輸入一個長度爲101的字符串,你將會有一個緩衝區溢出,這會導致錯誤或者甚至更糟的是安全性問題。更好的選擇通常是fgets,它允許輸入字符串的大小限制。

+1

可以使用scanf指定長度。 'scanf(「%10s」,var);' – Leandro 2010-05-31 02:47:00

1

我邀請其他答覆者對這裏的指針和參考文獻進行一個很好的總結。我不認爲我能做到這一點,而不是在這裏或那裏犯一些錯誤,而且我也不打算處理隨之而來的書呆子狂怒。

因此,我只是指您一個好resource瞭解指針和引用,這是問題的核心。 http://www.cplusplus.com/doc/tutorial/pointers/

+0

+1對於典型的SO書呆子憤怒...有時似乎有一個比賽在某個地方看到誰可以發佈最多的「但是!但是!未定義的行爲OMG」在一天的評論。 – SoapBox 2010-05-31 02:53:11

0

當你使用像這樣的數組:

char name[20]; 

,你必須考慮到由20個字符組成的存儲區域與它關聯。要獲取該內存區域的開始地址,您必須使用數組的名稱,而要獲取該數組的單個字符的地址,則必須使用如下的sintax:& name [i]。
您正在使用scanf讀取一個字符串,該字符串是C中的一個char數組。scanf需要與要讀取的變量類型關聯的內存區的地址。在這種情況下,您正在讀取數組,因此您只需使用該名稱。 如果您想讀取單個變量而不是數組,則必須使用&符號。例如:

char myChar; 
scanf("%c", &myChar); 

我希望這會有所幫助。

1

scanf("%s", &var);中刪除&,因此它是scanf("%s", var);