ひらがなの文字列ねこ も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バイトの情報量で表され


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


それに対し


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


画像データに名づけられた数値データは


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


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


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


ですので 


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


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


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


次のプログラムのように



#include <stdio.h>


int main(void)

{

char a='b';


printf("%c",a);

return 0;

}


コンパイル結果


b


変数の型charにはシングルクォーテーション' 'を使って


英字1文字を格納することはできますが


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


ひらがなを変数の型charに格納しようとすると


とエラー文がでてきます。


#include <stdio.h>


int main(void)

{

char a='あ';


printf("%c",a);

return 0;

}


コンパイル結果


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

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

警告

multi-character character constant

(複合文字定数、


つまり


abcや

あいのように


いくつかの文字がくみあわされた定数と表示が出ています


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


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


ことを表しています。


数値1や文字aなども定数です


この場合 char a='あ';


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


abcや

あいのようなデータが格納されていると


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


あ は


abcや

あいのような


複合文字にあたるというわけですね。


この  あ  の場合は


画像データ ひらがな あ を呼び出すための


数値データは


半角英数字の画像データを呼び出すための数値データ(1バイト)


の2倍の


半角英数字2つ分の


2バイトの情報量を持つので


char a='あ';


のように


半角英数字1つ分の 1バイトの情報量


しか格納できないシングルクォーテーション''内に


2バイトの情報量をもつ あ のような複合文字定数を

 

格納することはできません。


ですので


警告

multi-character character constant


とエラー文がでています。


つまり


char型の変数には


アルファベットのような1バイト文字1文字


もしくは1バイトに格納できる


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


2バイト文字である 



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


このようなことがおこるのです」


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


アレサ

「すこしいいかえると


複合文字定数「あ」の画像データに


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


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


収めようとしているからエラー文がでてくるのです。」


ソーラー「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]='こ’


のように変数の型charに2バイトのデータ量をもつ


ひらがな ね、こ、を一文字ずつ格納することは


できないと


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


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


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


う~ん どのように ひらがな ね、こ、が


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表示されたものです。


そして


今回 試しに 


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出力変換指定子をつかわないといけないのではないですか・・



おもわれますの。」


ソーラー「あっほんとだ」


ソーラー「

それでは


%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出力表示すると


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



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


に 2バイト文字である


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


これなら ひらがな ね も


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


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


ひらがな ねこ


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


アレサ「


ねこの場合は


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


1100101010101010(2バイト)


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


1000111011011110(2バイト)


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


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

hairetu[1]には10101010(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]

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

この

がなぜ

コンパイル結果に表示されるのかは


残念


わからないんです」




このエピソードは


まだまだ仮説の段階です


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


                solarplexussより

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

作者を応援しよう!

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

応援したユーザー

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