ファイルオープンに成功したときファイルポインタ変数にNULL以外の戻り値が返されているのを確認してみよう
ポインタ変数の性質として
🌞 同じポインタ変数名hairetuをつかって 🌞
🌞 どんどん文字列を別々のメモリに格納でき 🌞
🌞 1番最後にメモリに格納された文字列データを 🌞
🌞 格納しているメモリのアドレスが 🌞
🌞 ポインタ変数であるhairetuに格納される。 🌞
のような仕組みがあったけれど
ファイルポインタ変数は
それをさらにパワーアップしたものになっています
その仕組みとは
同じファイルポインタ変数名fpをつかって
どんどんデータをメモリに格納できるのですが
ファイルポインタ変数fpに格納されている値は変化しません
つまり
ファイルポインタ変数fpに格納されている値すなわちアドレスは
ずっと変化しないのです
別の言い方をすれば
ファイルポインタ変数fpはずっと1つの同じメモリのアドレスを
保持し続けます
それなのに
どんどんデータを別々のメモリに格納できるのです
ファイルポインタ変数fpはすごいですね
ただし
ファイルポインタ変数fpに格納されているアドレスは
ずっと変化しないんですが・・・
ファイルポインタ変数fpに格納されているアドレス先の
メモリに格納されているデータは
新しいデータがメモリに保存されるごとに
変化していきます
ポインタ変数の特徴として
ファイルポインタ変数fpに格納されているアドレスのメモリに格納されているデータは
fpに*をつけた
*fpであらわされるので
ハードディスクに保存されているデータが
新しくメモリに保存されるごとに
*fpの値は変化していきます
その様子を
ちょっとだけ
垣間見てみましょう。
まずは
次のプログラムを用いて
ハードディスクのTEN-GOGO-C-language.txtファイルに
1
2
3
4
5
を
保存してみよう。」
#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");
fprintf(fp,"%d\n",1);
fprintf(fp,"%d\n",2);
fprintf(fp,"%d\n",3);
fprintf(fp,"%d\n",4);
fprintf(fp,"%d\n",5);
fclose(fp);
return 0;
}
コンパイル結果(EAZY IDECの場合)
ビルド結果(Visual Studioの場合)
Hello!ファイルオープンに成功しましたよ~ん
ソーラー「これで
ハードディスクのTEN-GOGO-C-language.txtファイルに
1
2
3
4
5
が
保存されたわけだ。
この
ハードディスクのTEN-GOGO-C-language.txtファイルに
保存された
1
2
3
4
5
を
読み込んで
メモリに格納する際
fpや*fpがどのような値をもつかを
しらべてみよ~う」
🌻そうだね😊そうしよ🌻
ソーラー「そのプログラムは
次のようになるね。
いたるところに
fpや*fpがどのような値をもつかをしらべるために
printf("%p\n", *fp);
printf("%p\n", 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");
printf("%p\n", fp);
int hairetu[5];
fscanf(fp, "%d", &hairetu[0]);
printf("%p\n", *fp);
printf("%p\n", fp);
fscanf(fp, "%d", &hairetu[1]);
printf("%p\n", *fp);
printf("%p\n", fp);
fscanf(fp, "%d", &hairetu[2]);
printf("%p\n", *fp);
printf("%p\n", fp);
fscanf(fp, "%d", &hairetu[3]);
printf("%p\n", *fp);
printf("%p\n", fp);
fscanf(fp, "%d", &hairetu[4]);
printf("%p\n", *fp);
printf("%p\n", fp);
printf("%d\n", hairetu[0]);
printf("%d\n", hairetu[1]);
printf("%d\n", hairetu[2]);
printf("%d\n", hairetu[3]);
printf("%d\n", hairetu[4]);
fclose(fp);
return 0;
}
コンパイル結果
Hello!ファイルオープンに成功しましたよ~ん
032F4848
032FB009
032F4848
032FB00B
032F4848
032FB00D
032F4848
032FB00F
032F4848
032FB011
032F4848
1
2
3
4
5
🌻わ~すご~い
これどうなってるのかな
面白そうな結果が出てきたけど・・
🌼
ソーラー「ぼくもどきどきするな☆
まず
FILE *fp;
fp = fopen("TEN-GOGO-C-language.txt", "r");
if (fp == NULL) {
printf("ファイルオープンに失敗しましたよ~ん\n");
return -1;
}
else printf("Hello!ファイルオープンに成功しましたよ~ん\n");
が実行された後の
printf("%p\n", fp);
のコンパイル結果が
032F4848になっているのからみてみようかな😊」
🌻 🌻
032F4848
これはいったいなんなのか・・・か・・・
う~ん
なんだろう
何か意味があるのかな
🌼 🌼
ソーラー「意味はあるんだよ
そのカギとなっているのが
プログラムの冒頭の
ファイルポインタ変数宣言と
fopen関数の設定の命令文にあるんだよ。
FILE *fp;
fp = fopen("TEN-GOGO-C-language.txt", "r");
if (fp == NULL) {
printf("ファイルオープンに失敗しましたよ~ん\n");
return -1;
}
🌻 🌻 🌻
これと
printf("%p\n", fp);
のコンパイル結果の
032F4848
なにか関係あるの?
なんにも関係ないようなきがしない?
🌼 🌼
ソーラー「あるんです。
printf("%p\n", fp);
はそもそも
ファイルポインタ変数fpに格納されている数値
はっきり言うとアドレスをあらわすよね」
🌻 🌻
?
そういえば
"%p出力変換指定子は数値を16進数で表示するときに用いられていて
ポインタ変数が格納しているアドレスを表示するためにつかわれていた
ような気がするけど・・・
🌼 🌼
ソーラー「そう、
アドレスは普通は16進数であらわすルールになっているんだよ」
🌻 🌻
あ、そっか!
ファイルポインタ変数fpといっても
ポインタ変数には違いないから
アドレスを格納しているんだね
🌼 🌼
ソーラー「ファイルポインタ変数宣言
FILE *fp;
が行われると
ファイルポインタ変数fpが作製され
fopen関数の設定の命令文
fp = fopen("TEN-GOGO-C-language.txt", "r");
が行われて
TEN-GOGO-C-language.txtファイルのオープンに成功した場合
ファイルオープン関数fpは
NULL以外の戻り値を
かえされるんです。
だから
FILE *fp;
fp = fopen("TEN-GOGO-C-language.txt", "r");
if (fp == NULL) {
printf("ファイルオープンに失敗しましたよ~ん\n");
return -1;
}
の直後の命令文
printf("%p\n", fp);
によって表示されるファイルポインタ変数fpの格納している
16進数
032F4848
は
TEN-GOGO-C-language.txtファイルが
無事に開かれたとき
ファイルポインタ変数fpに戻される戻り値なんだね。」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます