scanf関数を使って空白を含んだ文字列Hello nyannkoを配列にとりこむとprintf関数を使ってHelloまでしか表示できません 配列内にどのように文字列は格納されているのでしょうか

ソーラー「では みなさ~ん、次はscanf関数を使って空白を


真ん中に含んだ文字列


Hello nyannko



char型の配列hairetuに格納できるか試してみましょ~~う。」


空白はどのようにあつかわれるのかな?


空白は文字として認識されるのかな?


プログラムは次のようになります

#pragma warning(disable: 4996)


#include <stdio.h>


int main(void)

{

char hairetu[10000];

scanf("%s",hairetu);

printf("%s\n",hairetu);


return 0;

}


ソーラー「


このプログラムをコンパイルして


アンダーバー

_


が表示される


入力待機中のコマンドプロンプト画面で


Hello nyannko 


とうちこむと・・・・・


コンパイル結果


Hello nyannko (と入力すると)

Hello (だけが表示されます)



ソーラー「残念!


空白を含んだ文字列データ


Hello nyannko


scanf("%s",hairetu);


を実行して


配列に格納したわけだけど


printf("%s\n",hairetu);


が実行されても


Helloまで


しかコマンドプロンプト画面にprintf出力表示されないね。


にゃんこちゃん でてこないね・・・


今日も元気かな?


これはいったいどうなっているのかな?」


アレサ 「このとき


文字列Hello nyannkoは


char hairetu[10000];


によって生成される文字のいれもの


char型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[5]

hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]

hairetu[10]

hairetu[11]

hairetu[12]

hairetu[13]

hairetu[14]

どのように

格納されているか

プログラムを構成して実行してみます


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void)

{

char hairetu[10000];

scanf("%s", hairetu);

printf("%s\n", hairetu);


printf("%c\n", hairetu[0]);

printf("%c\n", hairetu[1]);

printf("%c\n", hairetu[2]);

printf("%c\n", hairetu[3]);

printf("%c\n", hairetu[4]);

printf("%c\n", hairetu[5]);

printf("%c\n", hairetu[6]);

printf("%c\n", hairetu[7]);

printf("%c\n", hairetu[8]);

printf("%c\n", hairetu[9]);

printf("%c\n", hairetu[10]);

printf("%c\n", hairetu[11]);

printf("%c\n", hairetu[12]);

printf("%c\n", hairetu[13]);

printf("%c\n", hairetu[14]);

return 0;

}


コンパイル結果

Hello nyannko (と入力すると)

Hello (だけが表示されます)

H

e

l

l

o




アレサ「このとき


char型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[5]

hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]

hairetu[10]

hairetu[11]

hairetu[12]

hairetu[13]

hairetu[14]

には


hairetu[0]='H'

hairetu[1]='e'

hairetu[2]='l'

hairetu[3]='l'

hairetu[4]='o'

hairetu[5]='\0 '👈ここです

hairetu[6]='ㇷ'

hairetu[7]='ㇷ'

hairetu[8]='ㇷ'

hairetu[9]='ㇷ'

hairetu[10]='ㇷ'

hairetu[11]='ㇷ'

hairetu[12]='ㇷ'

hairetu[13]='ㇷ'

hairetu[14]='ㇷ'


と文字データが配列変数に格納されていますの


hairetu[5]='\0 '👈ここです


以降の配列変数

hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]

hairetu[10]

hairetu[11]

hairetu[12]

hairetu[13]

hairetu[14]


には


何もデータが格納されないので


printf("%c\n", hairetu[6]);

printf("%c\n", hairetu[7]);

printf("%c\n", hairetu[8]);

printf("%c\n", hairetu[9]);

printf("%c\n", hairetu[10]);

printf("%c\n", hairetu[11]);

printf("%c\n", hairetu[12]);

printf("%c\n", hairetu[13]);

printf("%c\n", hairetu[14]);


が実行されると


hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]

hairetu[10]

hairetu[11]

hairetu[12]

hairetu[13]

hairetu[14]


が初期化されていないときに最初から格納されているデータ



が表示されます


ここで


👈で示される


hairetu[5]='\0 '


が注目のポイントなんです。


ナル文字\0が格納されています


つまり


コンパイラは


Hello



コマンドプロンプト画面から


入力された時点で


Hello\0


とデータが入力されたと見なしているわけです。


そして


このナル文字\0も文字列の1部として


配列hairetuにとりこまれています。


ナル文字\0


配列変数

hairetu[5]に


hairetu[0]='H'

hairetu[1]='e'

hairetu[2]='l'

hairetu[3]='l'

hairetu[4]='o'

hairetu[5]='\0 '👈ここです


のように


格納されていると


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[5]

に格納されている文字データ

'H'

'e'

'l'

'l'

'o'

'\0 '

ひとまとまりの文字列データ


"Hello"


として


配列hairetuに格納されているとコンピュータには認識されます。


ですので


printf("%s\n", hairetu);


が実行されると


Hello


がコマンドプロンプトされるというわけです。



逆に次のプログラムのように


scanf関数をつかわず


直接


char hairetu[100]="Hello world";


を実行してみると


#include <stdio.h>


int main(void) {


char hairetu[100] = "Hello world";


printf("%s\n",hairetu);


return 0;


}


コンパイル結果


Hello world



空白部分もちゃんと


printf出力表示されます、


また


char hairetu[100];


によって生成される配列変数に


hairetu[0]='H';

hairetu[1]='e';

hairetu[2]='l';

hairetu[3]='l';

hairetu[4]='o';

hairetu[5]=' ';

hairetu[6]='n';

hairetu[7]='y';

hairetu[8]='a';

hairetu[9]='n';

hairetu[10]='n';

hairetu[11]='k';

hairetu[12]='o';

hairetu[13]='\0';



hairetu[5]=' \0';


のように


ナル文字\0でなく


hairetu[5]=' ';



本当の(笑)


空白スペースを


配列変数


hairetu[5]


に格納すると


配列に格納されている文字列データHello nyannkoを


次のプログラムのように


%s出力変換指定子をつかってprintf出力表示することができます。



#include <stdio.h>


int main(void)

{

char hairetu[100];

hairetu[0]='H';

hairetu[1]='e';

hairetu[2]='l';

hairetu[3]='l';

hairetu[4]='o';

hairetu[5]=' ';

hairetu[6]='n';

hairetu[7]='y';

hairetu[8]='a';

hairetu[9]='n';

hairetu[10]='n';

hairetu[11]='k';

hairetu[12]='o';

hairetu[13]='\0';


printf("%s\n",hairetu);


return 0;

}


コンパイル結果


Hello nyannko


ソーラー「なんと 半角空白スペースは


文字列データ


"Hello nyannko"


の1部になっているんだね。


つまり


空白もちゃんと文字データになっているんだ。


空白スペースが


ちゃんと文字列の1部とみなされるのはいいシステムだね。


このプログラムの


hairetu[5]に格納される文字を


hairetu[5]=' ';


のように空白から


次のようにナル文字\0に


hairetu[5]='\0';


とかきかえて


プログラムを実行してみると


#include <stdio.h>


int main(void)

{

char hairetu[100];

hairetu[0]='H';

hairetu[1]='e';

hairetu[2]='l';

hairetu[3]='l';

hairetu[4]='o';

hairetu[5]='\0';

hairetu[6]='n';

hairetu[7]='y';

hairetu[8]='a';

hairetu[9]='n';

hairetu[10]='n';

hairetu[11]='k';

hairetu[12]='o';

hairetu[13]='\0';


printf("%s\n",hairetu);


return 0;

}


コンパイル結果


Hello


アレサ「この場合は


hairetu[5]='\0';


の前の


hairetu[0]から

hairetu[4]までの配列変数に格納された文字達だけが


コマンドプロンプトにprintf出力表示されています。


hairetu[0]='H';

hairetu[1]='e';

hairetu[2]='l';

hairetu[3]='l';

hairetu[4]='o';

のように

格納されている文字データを


1まとまりの文字列データ"Hello"と


コンピュータに認識させるナル文字\0が


hairetu[5]='\0'と


格納されているため


コンピュータは


"Hello"という文字列データが


配列hairetuに格納されている認識します。


そのため


printf("%s\n",hairetu);


が実行されると


文字列Helloが


%s出力変換指定子によって


コマンドプロンプト画面にprintf出力表示されます。」


ソーラー「空白が配列変数に書き込まれた場合は


空白も文字列データの1部となるけど


配列変数に


ナル文字\0が書き込まれた場合は


それまでに配列変数に格納された文字データたちは


1まとまりの


文字列データとみなされるんだね。


そして


ナル文字\0は


それまでに配列変数に格納された文字データたちを


1まとまりの文字列データと


コンピュータに認識させるためにあるので


printf("%s\n",hairetu);


が実行されると


文字列Helloだけが


コマンドプロンプト画面に表示されるわけだ


だけど次のプログラムのように


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void)

{

char hairetu[10000];

scanf("%s", hairetu);

printf("%s\n", hairetu);


printf("%c\n", hairetu[0]);

printf("%c\n", hairetu[1]);

printf("%c\n", hairetu[2]);

printf("%c\n", hairetu[3]);

printf("%c\n", hairetu[4]);

printf("%c\n", hairetu[5]);

printf("%c\n", hairetu[6]);

printf("%c\n", hairetu[7]);

printf("%c\n", hairetu[8]);

printf("%c\n", hairetu[9]);

printf("%c\n", hairetu[10]);

printf("%c\n", hairetu[11]);

printf("%c\n", hairetu[12]);

printf("%c\n", hairetu[13]);

printf("%c\n", hairetu[14]);

return 0;

}


コンパイル結果

Hello nyannko (と入力すると)

Hello (だけが表示されます)

H

e

l

l

o




ソーラー「


ナル文字\0を格納している


配列変数 hairetu[5]の中に格納されているデータを


表示する


printf("%c\n", hairetu[5]);


の実行結果が


コンパイル結果


(空白)


となっていることから


ナル文字\0は空白スペースの役目を果たすのかと思い


Hello nyannkoをひとまとまりの文字データと認識させるために



hairetu[0] = 'H';

hairetu[1] = 'e';

hairetu[2] = 'l';

hairetu[3] = 'l';

hairetu[4] = 'o';

hairetu[5] = '';//🌞ここです

hairetu[6] = 'n';

hairetu[7] = 'y';

hairetu[8] = 'a';

hairetu[9] = 'n';

hairetu[10] = 'n';

hairetu[11] = 'k';

hairetu[12] = 'o';

hairetu[13] = '\0';


のかわりに


hairetu[0] = 'H';

hairetu[1] = 'e';

hairetu[2] = 'l';

hairetu[3] = 'l';

hairetu[4] = 'o';

hairetu[5] = '\0';//🌞ここです

hairetu[6] = 'n';

hairetu[7] = 'y';

hairetu[8] = 'a';

hairetu[9] = 'n';

hairetu[10] = 'n';

hairetu[11] = 'k';

hairetu[12] = 'o';

hairetu[13] = '\0';


ナル文字\0を


空白スペース


として文字データとして


Hello nyannko の


文字列データのなかに含めることはできないんだね。


こうなってくると


scanf関数をつかって


Hello nyannko


のような


空白を含んだ文字列データを


配列に格納することができないね


空白の部分は


\0とコンパイラに翻訳されて


コンピュータに伝えられてしまうからね


これはどうなってるのかな?」





つ 💖 づ 💖 く 💖・・・

  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます