ひらがなの文字列データ"ねこ"もscanf関数をつかって配列に格納することができます 



ひらがなの文字列データ"ねこ"もscanf関数をつかって配列に格納することができます 



アレサ 「ついに


文字列データ"neko"さんも配列内に格納できました。 


ここまできたんですの。」


ソーラー 「んでぇ~~ ここまでくると 


英語の文字列データ”neko”だけでなく


ひらがなの文字列データ”ねこ”を


配列hairetuに格納してみたくなるぅよね?よね?」


アレサ 「ひらがな・・・ですか?」


ソーラー


「では みなさ~ん、次はscanf関数を使って


ひらがなの文字列データ"ねこ"を


配列hairetuに格納してみましょう。


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


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void)

{

char hairetu[10000];

scanf("%s",hairetu);

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


return 0;

}


このプログラムを実行して


アンダーバーが表示された入力待機中のコマンドプロンプト画面で


キーボードから


ねこ 



うちこむと


ねこがprintf出力表示されます。


簡単ですね。」


アレサ 「ここです。このプログラムのポイントになるところは・・


英字a,b,cの画像データに割り当てられた数値データは


1バイトの情報量で表され


1バイトのメモリ領域に格納されます。


それに対し


日本語のあ、い、う、え、お・・・などの


画像データに割り当てられた数値データは


2バイトの情報量で表され


メモリ内の2バイトの領域にわたって


格納されることになっています。


ですので 


通常は1バイト分のメモリしか格納領域を持たないchar型の変数には


ひらがなは格納できないんです。


そのことをプログラムを組んで確かめてみます。


次のプログラムをご覧ください。

👇


#include <stdio.h>


int main(void)

{

char a='b';


printf("%c",a);


return 0;

}


プログラムの実行結果


b


このプログラムのように


char型の変数aに


bにシングルクォーテーション' 'を用いた


文字データ'b'を格納することはできますが


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


ひらがな



にシングルクォーテーション' 'を用いた


'あ'


をchar型の変数aに格納しようとすると


エラー文がでてきます。


#include <stdio.h>


int main(void)

{

char a='あ';


printf("%c",a);

return 0;

}


EAZY IDECの場合


プログラムの実行結果


ファイル「C:/Users/solarplexuss/AppData/Local/EasyIDEC/project/iiiii/main.c」の

「5行目」で記述エラーを発見しました。

警告

multi-character character constant

(複合文字定数という意味です)


Visual Studioの場合



ソーラー「


定数とは 変数に格納される


数値データや文字データなどの一定の値を持つデータの


ことを表しています。


数値データ1や文字データ'a'なども定数で


1バイトのデータ量を持っています


複合文字定数とは


2バイト以上のデータ量を持っている定数なんです


この場合 char a='あ';


の'あ'は


複合文字定数



コンピュータに認識されています。


シングルクォーテーション' '内には


半角英数字のように


1バイトのデータ量を持つデータ(1バイト文字)しか格納できない仕組みとなっていますので

2バイトのデータ量を持つデータ(2バイト文字)


あ をシングルクォーテーション' '内に記述する


         'あ'


のような記述方法は間違っていますのでご注意ください



つまり


char型の変数には


'a'、'b'、'c'


つまり


a,b,cのようなアルファベットのような1バイト文字1文字分のデータ


もしくは1バイトのメモリに格納できる


-128~127までの数値データしか格納できないため


2バイトのデータ量を持つ


'あ'



char型の変数に格納しようとすると


ビルドエラーが表示されるのです」


ソーラー「そう、そのようだね。」


アレサ

「すこしいいかえると


もともと


「あ」の画像データに


つけられた数値データ情報は2バイトありますので


1バイトしか格納容量のないchar型の変数aに'あ'を


格納することはできないのですね」


ソーラー「char型の変数にはひらがなのデータは格納できないっと」


アレサ「


ならば


さきほどのプログラム


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void)

{

char hairetu[10000];

scanf("%s",hairetu);

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


return 0;

}

において


配列宣言char hairetu[10000];によって


生成される


char型の配列変数は


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[9999]


のようになっているはずですが


ひらがな ねこ を


このchar型の配列変数に格納する際


hairetu[0]='ね’

hairetu[1]='こ’


のように


1バイトのデータ格納容量をもつchar型の配列変数


hairetu[0]

hairetu[1]


に2バイトのデータ量をもつ


ひらがな



を1文字ずつ格納することは


できないと


みなさん おもわれるのではないですか😊?」


ソーラー 「あっ そういえば そうだよね。


よくきづいたよね。すごいな。


う~ん どのように


ひらがな




char型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[9999]


に格納されているか?・・・か


そうだ


ねえ、アレサ


さっきのプログラムで


ひらがな ねこ を


printf出力表示できているから


char型の配列hairetuに


ひらがな ねこ


は格納できてるはずだよね


となると


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[9999]


のなかに 


ひらがな



のデータがかくれているのだけは間違いないよね」


アレサ「そうなのですの」


ソーラー「だったら


char型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[9999]



なにが格納されているか直接printf出力表示してみればいいんじゃない?


とりあえず 確かめてみる」


アレサ 「(^^)そうです、その方法があったのですの。


早速プログラムを組んで


char型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[9999]


に個別に


何が格納されているか確かめてみます。


とりあえず


次の8つのchar型の配列変数のなかに


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[5]

hairetu[6]

hairetu[7]


何が格納されているか確かめてみます。


そのプログラムはこちらです

👇


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void)

{

char hairetu[10000];

scanf("%s",hairetu);

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

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

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

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

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

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

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

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

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


return 0;

}


アレサ「👆


このプログラムを実行すると


_


アンダーバーだけが表示されます。


この入力待ち受け中のコマンドプロンプト画面で


ねこ 


とうちこむと・・・


???な、なにかパソコンの動作がおかしいです。


www.exeは動作を停止しました


???


ですが、コンパイル画面には


ねこ(と入力すると)

ねこ


と表示されています。」


ソーラー「今


コマンドプロンプト画面に表示されている


ねこ(と入力すると)

ねこ



のうち

1番目の行に表示されている


ねこ は 命令文scanf("%s",hairetu);


のはたらきにより

入力するよううながされ

私たちがうちこんだものです



2番目に表示されている


ねこ


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


のはたらきにより


char型の配列hairetuに格納された 


ねこ 


がprintf表示されたものです。


そして


今回 試しに 

char hairetu[10000];

scanf("%s",hairetu);

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


の他に


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

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

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

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

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

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

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

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


の命令文を


追加して実行しましたが


何も反応がなく


コマンドプロンプト画面に


ねこ(と入力すると)

ねこ


までしか表示されていません。


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[5]

hairetu[6]

hairetu[7]

に 


どのように


文字ねこが格納されているか・・・は確認できないんです・・・・・」


ソーラー「


やるな😊 コンピュータ


ふふふ」


アレサ「ソーラーさん 


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

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

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

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

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

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

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

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


ではなく


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[4]);

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


のように

char型の配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[5]

hairetu[6]

hairetu[7]

に格納されている文字をprintf出力表示するには


%s出力変換指定子でなく

%c出力変換指定子をつかわないといけないのではないですか・・



おもわれますの。」


ソーラー「あっほんとだ そうだった」


ソーラー「それでは


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

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

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

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

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

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

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

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


ではなく


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[4]);

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



%s出力変換指定子でなく

%c出力変換指定子に置き換えた


次のプログラムを


#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]);

return 0;

}


アレサ ソーラー「プログラムを実行😊」



プログラムの実行結果


_


ソーラー「アンダーバーが表示されるので


ねこ



入力すると・・・」





プログラムの実行結果


ねこ

ねこ



ソーラー「プログラムを実行できた\(^o^)/」


アレサ「プログラムを実行できましたの!(^^)!」



アレサ「 ソーラーさん 


このような結果になったのは


ひらがな ね を表す数値データが


次のように2バイト(16ビット)


1100101010101010で表されているとすると


char hairetu[10000]によって生成される配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[9999]


まずは

hairetu[0]に


1100101010101010の右から8ビット分の


10101010が収められ


その次に


hairetu[1]に


1100101010101010の


のこり左から8ビット分の


11001010がおさめられているからだとおもわれますの。


つまり


画像データ ね を呼び出す数値データが


2バイトの情報量をもっていたとしても


char型の配列変数

hairetu[0]

hairetu[1]


に1バイトずつ分割して


格納できるのではないでしょうか?


char型の配列変数


hairetu[0]だけに


画像データ ね を呼び出す数値データ


が格納されるわけではないというわけです


そして


hairetu[0]に格納された10101010

hairetu[1]に格納された11001010



   %c出力変換指定子を使って


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

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

を実行し

printf出力表示すると


が表示されたということなのではないですの?


hairetu[0]に格納された10101010

hairetu[1]に格納された11001010


の画像データに対応するデータというわけです


1バイトしか格納容量のないchar型の変数a


に 2バイト文字である


ひらがな ね を格納することはできなくても


これなら ひらがな ね を


char型の配列 hairetu[10000]に格納することができるわけです。」


ソーラー「なあるほど と、なると 


ひらがな ねこ



char hairetu[10000]に格納する場合は・・・😊」 


アレサ「


ねこの場合は


ね の画像データにつけられた数値データが


1100101010101010(2バイト)


こ の画像データに名づけられた数値データが


1000111011011110(2バイト)


のように表されているとすると


hairetu[0]には11001010(1バイト)

hairetu[1]には11001010(1バイト)

hairetu[2]には11011110(1バイト)

hairetu[3]には10001110(1バイト)


のように 4分割されて


ね と こ の画像データにつけられた数値データが


格納されているとおもわれますの。


hairetu[0]に格納された10101010

hairetu[1]に格納された11001010

hairetu[2]に格納された11011110

hairetu[3]に格納された10001110



      🌞%c出力変換指定子を使って🌞


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

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

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

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


👆のようにprintf出力表示すると



が表示されるのですが

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

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


の実行結果が

同じ

となっているのは


hairetu[0]に格納された10101010

hairetu[2]に格納された11011110

に対応する文字データがないため



と表示されたのではないかと思われますの」



ソーラー「そっか😊


そうかもしれないね。


char hairetu[10000];のように


      「char型の配列宣言がおこなわれている場合は」



半角英数字1文字しか格納できないchar型の変数aに


文字データを格納するときと違って


データを格納するいれものが


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[9999]


のように


たくさんできているので


データ量が合計4バイトになる ねこ を


1バイトずつ分割しながら


十分、余裕で格納できるんだね。


だから


文字列データ"ねこ"は

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

に1バイトずつ分割されて格納され

最後に

hairetu[4]にナル文字\0が格納されるわけなんだね。



このプログラム

👇

#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]);

return 0;

}


プログラムの実行結果

ねこ

ねこ




ソーラー「👆の


プログラムの実行結果の

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

に格納されていたデータをprintf出力表示したもので

に続く空白スペースは


hairetu[4]


に格納されていたナル文字をprintf出力表示したもののようですね



それにつづく

hairetu[5]

hairetu[6]

hairetu[7]

に格納されていたデータを

%c出力変換指定子を用いて

printf出力表示したもののようですね」




このエピソードは


まだまだ仮説の段階です


もうすこし検証が必要とおもわれます


                solarplexussより

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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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