天国にいけるC言語入門 ヘキサ構造体 ver5.2130
fgets関数をつかってハードディスク内のファイルに保存された文字列から複数の文字を用意した配列に格納しコマンドプロンプト画面に表示してみよう
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関数と一緒、似ているね。
🌼 🌼
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます