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

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



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


真ん中に含んだ文字列データ


"Hello nyannko"



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


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


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


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


#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出力表示されます


ダブルクォーテーションで囲まれた文字列データ


例えば


"Hello world"


などは


たとえ文字列の中に空白部分があったとしても


文字列の最後にナル文字\0 がくっついているとみなされます



また


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"をひとまとまりの文字列データと認識させることができる

ナル文字\0の前までが一塊の文字列データと認識される

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';


を実行しても


Hello nyannkoは


ひと固まりの文字列データとは認識されないんだね


ナル文字\0は


空白スペースの役割をはたさないというわけなんだ




scanf関数をつかって


キーボードから


Hello nyannko


と打ち込んでも


文字列データ

"Hello"


を入力したことになり


文字列データ

"Hello nyannko"


を入力したことにならない


空白の部分は


\0を打ち込んだことになってしまうからね


じゃあ


scanf関数をつかって


キーボードから


Hello nyannko


と打ち込んだとき


文字列データ

"Hello nyannko"


を入力したことにするにはどうしたらいいのかな?」





つ 💖 づ 💖 く 💖・・・

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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る