2013-05-15 8 views
5

シンプルなCプログラムを実行しようとしていますが、形式: '%s' は 'チャー' と入力期待が、引数2は、型を持つ 'CHAR()を[20]'」GCC 4.2.1C - 警告:フォーマット '%s'はタイプ 'char *'を想定していますが、引数2は 'char(*)[20]'タイプです。

#include <stdio.h> 

int main() 
{ 
    char me[20]; 

    printf("What is your name?"); 
    scanf("%s",&me); 
    printf("Darn glad to meet you, %s!\n",me); 

    return(0); 
} 
を用いて端末にコンパイル

実行のMac OSXマウンテンライオン

答えて

17
scanf("%s",&me); 

は、

scanf("%s",me); 

、について説明:

"%s"scanfはchar配列の最初の要素へのポインタを期待していることを意味します。 meはオブジェクト配列であり、ポインタとして評価することができます。だからこそ、に直接&を追加せずに使うことができます。 me&を追加する‘char (*)[20]’に評価されますと、あなたのscanfはchar *

コード評論家を待っている:長さ> 20と、ユーザの入力文字列がそう"%19s"に変更した場合"%s"を使用して

は、バッファオーバーフローを引き起こす可能性があります:それはsizeofのオペランド、_Alignof、または単項&事業者である場合を除き

scanf("%19s",me); 
+3

本当に '&'演算子を使いたいのであれば、なぜ* why * too – Mike

+2

または '...、&me [0])'を説明するといいでしょう。 – alk

+4

@Mikeなぜなら、コンパイラの警告は、なぜかあなたに明確に伝えます。 –

3

、またはI "N要素配列T"の式は、 "Tへのポインタ"型の式に変換( "decay")されます。配列内の最初の要素のアドレス。

meは、charの20要素の配列として宣言されています。通常、の式meがコード内に現れると、 "charへのポインタ"の式として扱われます。あなたが書いたのであれば、

scanf("%s", me); 

あなたはエラーが発生していないでしょう。式meは正しい型の式に変換されているはずです。

ただし、&演算子を使用すると、そのルールはバイパスされています。代わりにcharへのポインタを、あなたはscanfが故に、%s変換指定するための診断期待するものではありません配列charchar (*)[20])の、へのポインタを渡しています。

+0

/バイパスされた/別の道を/ /、またはこれらの線に沿った何か、おそらく。ルールのため、結果は異なります。引用には+1を付けてください。 – Sebivor

+0

注: '_Alignof'は標準で削除されたN1570の間違いです。 '_Alignof'のオペランドは、任意の式ではなく、' _Alignof(type-name) '型なので、意味があります。 –

+0

@DanielFischerあなたはこの1つを見ていただけますか?私が指摘している "異常"はかなり明確です。最後のトークンについては、文字列に必要な2つの区切り文字ではなく、最後の区切り文字とNULL文字の間ですトークン - http://stackoverflow.com/questions/16571060/strtok-issue-if-tokens-are-delimited-by-delimiters-why-is-last-token-between –