fgets関数をつかってハードディスク内のファイルに保存された文字列から複数の文字を用意した配列に格納しコマンドプロンプト画面に表示してみよう

🌻   🌻 


          🌻


今度は

ハードディスク内のファイルに保存された文字列データから

1文字だけ

読み取るのでなく


ハードディスク内のファイルに保存された文字列データから


            複数の文字を

読み取ってみよう


🌼  🌼


そのためには

まず

ハードディスク内のTEN-GOGO-C-languageファイルに

何か文字列が保存されてないとね💖


次のプログラムを使って


ハードディスク内のTEN-GOGO-C-languageファイルに文字列データ


omusubi


を保存してみるよ


🌼      🌼


#pragma warning(disable: 4996)


#include <stdio.h>


int main (void){


FILE *fp;


fp=fopen("TEN-GOGO-C-language.txt","w");


if(fp==NULL){


printf("ファイルオープンに失敗しましたよ~ん\n");


return -1;}


else printf("Hello!ファイルオープンに成功しましたよ~ん\n");


fputs("omusubi\n",fp);


fclose(fp);


return 0;


}



コンパイル結果


Hello!ファイルオープンに成功しましたよ~ん




ソーラー「これで


TEN-GOGO-C-language.txtファイルに


文字列データ

omusubi


が保存されたわけだね。」



🌻🌻


さあて


さて


今度は

fgets関数を使って


ハードディスク内のファイルに保存された文字列データ


omusubiから

       

複数の文字を


読み取り


コマンドプロンプト画面に表示してみるよ


複数の文字を読み取るということは


ハードディスク内のファイルに保存された長い文章のようなものでも


読み取れることになるね


だから


fgets


つまり

file(ファイル)

get(得る)

sentense(文章)


というわけなんだね。


fgetcなら

file(ファイル)

get(得る)

character(文字)

というわけさ。😊


🌼🌼




#pragma warning(disable: 4996)

#include <stdio.h>


int main(void) {


FILE *fp;

fp = fopen("TEN-GOGO-C-language.txt", "r");


if (fp == NULL) {

printf("ファイルオープンに失敗しましたよ~ん\n");

return -1;

}


else printf("Hello!ファイルオープンに成功しましたよ~ん\n");



char str[10];

fgets(str,8,fp);

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


fclose(fp);


return 0;

}




コンパイル結果


Hello!ファイルオープンに成功しましたよ~ん

omusubi

続行するには何かキーをおして下さい・・・_



ソーラー「fgets関数をつかって


文字列データ

omusubi

printf出力表示することができた\(^o^)/


このfgets関数の


ハードディスク内TENのTEN-GOGO-C-language.txtファイルに保存された


文字列データomusubi


から複数の文字を読み取る仕組みはどうなっているのかな」



🌻🌻🌻


まず

配列宣言

char str[10];

を行うことにより

文字列データomusubi

をコンピュータのメモリに格納するための

配列変数

str[0]

str[1]

str[2]

str[3]

str[4]

str[5]

str[6]

str[7]

str[8]

str[9]

用意します。


そして

fgets(str,8,fp);

により

第2引数に書き込まれた8により

ファイルポインタ変数fpが格納しているアドレスのメモリに集められる

文字列データomusubi

の7文字と


        さらに末尾に\0を付け加えた


8文字

o

m

u

s

u

b

i

\0


char str[10];

により生成される

配列変数

str[0]

str[1]

str[2]

str[3]

str[4]

str[5]

str[6]

str[7]


str[0]=’o’;

str[1]=’m’;

str[2]=’u’;

str[3]=’s’;

str[4]=’u’;

str[5]=’b’;

str[6]=’i’;

str[7]=’\0’;

と格納されます。


つまり

\0と文字列データomusubi

あわせて

8文字が

配列変数に格納されるんだね。


残りの


char str[10];

により生成された

配列変数

str[8]

str[9]


には格納される文字データがないので


初期化されることはないので


str[8]

str[9]


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


が格納されたままとなってるんだ🌞


str[8]

str[9]

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

次のプログラムを使って求めてみるよ。


#pragma warning(disable: 4996)

#include <stdio.h>


int main(void) {


FILE *fp;

fp = fopen("TEN-GOGO-C-language.txt", "r");


if (fp == NULL) {

printf("ファイルオープンに失敗しましたよ~ん\n");

return -1;

}


else printf("Hello!ファイルオープンに成功しましたよ~ん\n");



char str[10];

fgets(str, 8, fp);

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

printf("%d\n", str[8]);

printf("%d\n", str[9]);


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

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

fclose(fp);


return 0;

}



コンパイル結果


Hello!ファイルオープンに成功しましたよ~ん


omusubi

-52

-52

続行するには何かキーをおして下さい・・・_



ソーラー「

つまり

str[0]='o';

str[1]='m';

str[2]='u';

str[3]='s';

str[4]='u';

str[5]='b';

str[6]='i';

str[7]='\0';

str[8]='ㇷ';

str[9]='ㇷ';


と文字データが配列に格納されていて


ㇷの画像データに割り振られている番号は-52ということになるかな


実際に


printf("%c\n", -52);

printf("%c\n", -51);


を実行すると

コンパイル結果

が表示されます


printf("%c\n", -51);


はおまけです


文字の画像データには数値が割り振られていて


%c出力変換指定子は


その数値に対応している画像データを表示する働きがあったよね。



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


のコンパイル結果が


omusubi


とあらわされていることから


配列strには


文字列データ"omusubi"が格納されていることになっているのがわかります


このように


配列の配列変数に格納された文字列データは


\0の前までが


配列に格納されている


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


この場合は


str[0]='o';

str[1]='m';

str[2]='u';

str[3]='s';

str[4]='u';

str[5]='b';

str[6]='i';

str[7]='\0';

str[8]='ㇷ';

str[9]='ㇷ';



str[7]=’\0’;


より前の


str[0]='o';

str[1]='m';

str[2]='u';

str[3]='s';

str[4]='u';

str[5]='b';

str[6]='i';


と配列変数に格納された


omusubiまでが


配列に格納されている


1つの連続した文字列データとみなされるので


配列str内に格納された文字列データを


printf出力表示する命令文

printf("%s",str);

を実行すると


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


omusubi


が表示されるんだね。



🌼  🌼



ソーラー「


というわけで


このプログラムで


fgets(str,8,fp);

fgets(str,2,fp);


と変更して記述すれば


omusubiの


'o'と


'\0'が


配列


str[0]

str[1]


に格納され


配列str内に保存された文字列データを


printf出力表示する命令文

printf("%s",str);

を実行すると


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


o


が表示されるんだね



じゃ


fgets(str,2,fp);

fgets(str,2,fp);

fgets(str,2,fp);

を実行したら


コンパイル結果はどうなるのかな?


ちょっと楽しそうだね


#pragma warning(disable: 4996)

#include <stdio.h>


int main(void) {


FILE *fp;

fp = fopen("TEN-GOGO-C-language.txt", "r");


if (fp == NULL) {

printf("ファイルオープンに失敗しましたよ~ん\n");

return -1;

}


else printf("Hello!ファイルオープンに成功しましたよ~ん\n");



char str[10];

fgets(str,2,fp);

fgets(str,2, fp);

fgets(str,2, fp);


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


fclose(fp);


return 0;

}


コンパイル結果


Hello!ファイルオープンに成功しましたよ~ん

u


ソーラー「なんで


uが表示されるのかな?」


🌻🌻

ほんとだね・・・

🌼


ソーラー「fgetc関数の時と似ている・・?」


🌻🌻

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

fgetc関数

fgets関数

は面白い仕組みになってるね


🌼  🌼


ソーラー「ははあ


わかったよ」



ソーラー「ハードディスクのファイル内のデータは


fgets(str,2,fp);


が実行されると


まず


ファイルポインタ変数fpの格納しているアドレスのメモリに宛てて


格納されます


fgets関数は


ファイルポインタ変数fpの格納しているアドレスのメモリ


からデータを読み込んで


配列に格納していくんだ



fgets(str,2,fp);


が1回実行されると


まず

omusubiの

先頭の

'o'と

'\0'が


ファイルポインタ変数fpの格納しているアドレスのメモリに集められ


次に


str[0]

str[1]


に格納される


もう1度


fgets(str, 2, fp);


がおこなわれると


fgets関数は


前に読み取られた


omusubiの


oの次の

'm'と

'\0'を


ファイルポインタ変数fpの格納しているアドレスのメモリに集め


次に


'm'と

'\0'


str[0]

str[1]


に格納するんだね


だから


前に

str[0]

str[1]


に格納されていた

'o'と

'\0'が

消去されて


'm'と

'\0'が上書きされているんだね。


さらに


さらにもう1回


fgets(str, 2, fp);


がおこなわれると


fgets関数は


前に読み取られた


omusubiの


'm'の次の

'u'と

'\0'を


ファイルポインタ変数fpの格納しているアドレスのメモリに集め


次に

str[0]

str[1]


に格納するんだね


だから


前に

str[0]

str[1]


に格納されていた

'm'と

'\0'が

消去されて


'u'と

'\0'が上書きされているんだね。


そして


配列strの配列変数


str[0]には

'u'

str[1]には

'\0'が格納されているので


配列strには


文字列データ"u"


が格納されていることになるので


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


が行われることにより


uが


コマンドプロンプト画面に表示されるというわけなんだ



では


fgets(str,2,fp);

fgets(str,2,fp);

fgets(str,2,fp);

でなく

fgets(str,3,fp);

fgets(str,3,fp);

fgets(str,3,fp);

を実行したら


コンパイル結果はどうなるのかな?


いや、もうわかったかな?


#pragma warning(disable: 4996)

#include <stdio.h>


int main(void) {


FILE *fp;

fp = fopen("TEN-GOGO-C-language.txt", "r");


if (fp == NULL) {

printf("ファイルオープンに失敗しましたよ~ん\n");

return -1;

}


else printf("Hello!ファイルオープンに成功しましたよ~ん\n");



char str[10];

fgets(str,3,fp);

fgets(str,3, fp);

fgets(str,3, fp);


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


fclose(fp);


return 0;

}


コンパイル結果


Hello!ファイルオープンに成功しましたよ~ん

ub


ソーラー「コンパイル結果はub


ub!」


🌻🌻

驚いてる・・・

🌼


ソーラー「ちょっと面白いコンパイル結果だね」


🌻🌻


これはどういう仕組みになってるのかな?


🌼  🌼


ソーラー「ははあ


これも わかったよ」



ソーラー「ハードディスクのファイル内のデータは


fgets(str,3,fp);


が実行されると


まず


ファイルポインタ変数fpの格納しているアドレスのメモリに宛てて


格納されます


fgets関数は


ファイルポインタ変数fpの格納しているアドレスのメモリ


からデータを読み込んで


配列に格納していくんだ



fgets(str,3,fp);


が1回実行されると


まず

omusubiの

先頭の

'o'と

'm'

'\0'が


ファイルポインタ変数fpの格納しているアドレスのメモリに集められ


次に


str[0]

str[1]

str[2]

に格納される


もう1度


fgets(str, 3, fp);


がおこなわれると


fgets関数は


前に読み取られた


omusubiの


mの次の

'u'

's'

'\0'を


ファイルポインタ変数fpの格納しているアドレスのメモリに集め


次に


'u'

's'

'\0'を


str[0]

str[1]

str[2]


に格納するんだね


だから


前に

str[0]

str[1]

str[2]


に格納されていた

'o'

'm'

'\0'が

消去されて


'u'

's'

'\0'

が上書きされているんだね。


さらに


さらにもう1回


fgets(str, 3, fp);


がおこなわれると


fgets関数は


前に読み取られた


omusubiの


's'の次の

'u'

'b'

'\0'を


ファイルポインタ変数fpの格納しているアドレスのメモリに集め


次に

str[0]

str[1]

str[2]


に格納するんだね


だから


前に

str[0]

str[1]

str[2]

に格納されていた

'u'

's'

'\0'

消去されて


'u'

'b'

'\0'

が上書きされているんだね。


そして


配列strの配列変数


str[0]には

'u'

str[1]には

'b'

str[2]には

'\0'が格納されていると


配列strには


文字列データ"u"


が格納されていることになるので


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


が行われることにより


uが


コマンドプロンプト画面に表示されるというわけなんだ





🌻🌻🌻


fgets関数は先に読み取った文字列の最後の文字の次の文字を先頭として


ファイルポインタ変数fpの格納しているアドレスのメモリに


読み込んでいくんだね


fgetc関数と一緒、似ているね。


🌼  🌼




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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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