C言語初心者です。次の二つのコードについて質問があります。

strinput02.cでは、文字列の入力が出来ず、上手く動作しません。
ところが、01の用に書くと上手くいきます。
01も02もポインタを引数としてscanfに渡していると思うのですが、
なぜ02では上手くいかないのでしょうか?
文字のポインタ宣言した後に、文字列のアドレスを代入しないといけないということなのでしょうか?


//strinput01.c

#include <stdio.h>

int main()
{
char szStr[32];
char *str;

str = szStr;

printf("文字列を入力してください----");
scanf("%s", str);
printf("%s¥n", str);

return 0;

}



//strinput01x.c

#include <stdio.h>

int main()
{
char *str;

printf("文字列を入力してください----");
scanf("%s", str);
printf("%s¥n", str);

return 0;

}

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2009/02/04 23:23:28
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:hyo-suke No.1

回答回数43ベストアンサー獲得回数5

ポイント30pt

01も02もポインタを引数としてscanfに渡していると思うのですが、

なぜ02では上手くいかないのでしょうか?

文字のポインタ宣言した後に、文字列のアドレスを代入しないといけないということなのでしょうか?

ポインタ(例で言う char *str;)は、単に str という矢印を作っただけです。

その先には文字列を入れるための領域を確保してあげる必要があります。

例01では char szStr[32]; という宣言がその領域になっており、

str = szStr;

でその領域を指し示しているため、scanf()が成功しています(szStr[32]に書き込めます)。

しかし例02では矢印(ポインタ)を宣言しただけで、その先には何もありません(見ず知らずの他人の領域を指しています)。

そのため怒られている(エラーとなる)のです。

ちなみに例01の char szStr[32]; の szStr というのも矢印に相当するので、次のようにも書けます。

//strinput01-2.c

#include <stdio.h>

int main()
{
char szStr[32];

printf("文字列を入力してください----");
scanf("%s", szStr);
printf("%s¥n", szStr);

return 0;

}
<||

#どのみち、31文字以上の文字列を入力するとまずいですが。
id:gbs01

回答ありございます。

2009/02/04 23:20:50

その他の回答2件)

id:hyo-suke No.1

回答回数43ベストアンサー獲得回数5ここでベストアンサー

ポイント30pt

01も02もポインタを引数としてscanfに渡していると思うのですが、

なぜ02では上手くいかないのでしょうか?

文字のポインタ宣言した後に、文字列のアドレスを代入しないといけないということなのでしょうか?

ポインタ(例で言う char *str;)は、単に str という矢印を作っただけです。

その先には文字列を入れるための領域を確保してあげる必要があります。

例01では char szStr[32]; という宣言がその領域になっており、

str = szStr;

でその領域を指し示しているため、scanf()が成功しています(szStr[32]に書き込めます)。

しかし例02では矢印(ポインタ)を宣言しただけで、その先には何もありません(見ず知らずの他人の領域を指しています)。

そのため怒られている(エラーとなる)のです。

ちなみに例01の char szStr[32]; の szStr というのも矢印に相当するので、次のようにも書けます。

//strinput01-2.c

#include <stdio.h>

int main()
{
char szStr[32];

printf("文字列を入力してください----");
scanf("%s", szStr);
printf("%s¥n", szStr);

return 0;

}
<||

#どのみち、31文字以上の文字列を入力するとまずいですが。
id:gbs01

回答ありございます。

2009/02/04 23:20:50
id:eternie No.2

回答回数10ベストアンサー獲得回数1

ポイント25pt

ポインタ変数というのはメモリ上で,ある変数のある位置 (アドレス) を記録しているだけであって実体がありません。

ポインタ変数を宣言しただけで初期化していないと,引数として渡された scanf は,どこを指し示しているのかがわからないから読み書きできないわけです。

一方,

char szStr[32];;
char *str;

str = szStr;

とすると,変数 str には szStr[0] のアドレスが代入されていて,scanfの引数として,strの値,すなわち szStr のアドレスが渡されて

szStr を読み書きできるということになります。

id:gbs01

回答ありがとうございます。

2009/02/04 23:21:49
id:GoldenDawn No.3

回答回数426ベストアンサー獲得回数81

ポイント25pt

scanf で返される値を受け取るメモリ領域はあらかじめ自分で確保しておく必要があります。

ポインタだけ用意しても scanf が適当な場所に結果を格納して返してくれたりはしません。

char szStr[32];

char *str;

str = szStr;

これでも良いですが、

char str[32] ;

のほうが簡単です。

id:gbs01

回答ありがとうございます。

2009/02/04 23:22:43
  • id:quintia
    C言語以外で知っているプログラミング言語があれば、それを書くといいかと思いますよ。

この質問への反応(ブックマークコメント)

トラックバック

  • 鍛錬記 - 一段落 2009-02-04 23:17:28
    一段落 とりあえず線型の再試験に向けたハードルであるレポートは終わり。明日は微積分の再試験がありますが,確実に取れるところから取らないとという感じです。 4月からはいままで
「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません