👇ハードディスク内に保存されているデータを利用する場合も、ハードディスク内に保存されているデータはコンピュータのメモリに保存されてから利用可能となります

ハードディスク内に作成したファイルをオープンモード"r"で開きデータを読み込んでみます 

おきた?おきた?😊



ソーラー「はうあ」


ハードディスク内に作成したファイルに新規書き込みできるよう

ファイルを開く

オープンモード"w"


ハードディスク内に作成したファイルに追加書き込みできるよう

ファイルを開く

オープンモード"a"


につづき


ハードディスク内に作成したファイルに保存されたデータの読み込みのみ

できるよう

ファイルを開く

オープンモード"r"


も紹介します。


オープンモード"r"では 


以前に

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


保存されたデータを


コンピュータのメモリに読み取りのみができる状態に


ファイルを開く

(ファイルポインタ変数fpを使ってファイルにアクセスできる状態にする)


ことができます。


ですので


fprintf関数などをつかって


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


データを書き込むことはできません


データの書き込みはできないのですが


コンピュータのメモリに


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


保存されているデータを


読み取ることはでき


読みとったハードディスク内のTEN-GOGO-C-language.txtファイルに


保存されているデータは


コマンドプロンプト画面にprintf関数をつかって


表示することができます。


これも試してみる?


   🌻     🌻


ソーラー「わあおぉう!」


🌻

何かになりきっている・・・

🌼



ソーラー「あ・・、お願い」



🌻

とりあえず


復習もかねてみようよ。


まずはオープンモード"w"で


ハードディスク内のTEN-GOGO-C-language.txtファイルを開き


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


保存されていたデータを初期化(消去)してから


新たに


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

数値データ

1

2

3

4

5

を書きこんでみようよ


このとき


12345や1,2,3,4,5ではなくて


1

2

3

4

5


データをTEN-GOGO-C-language.txtファイルに保存したいんだけど・・


どう?


難しい?


🌼


ソーラー「はひ 簡単です


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


のように


fprintf関数にエスケープシーケンス\nを使って


ソースコードを記述すれば


1

2

3

4

5

のように


1行ずつ改行して


ハードディスク内の


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


1

2

3

4

5


を保存することができるはずだよ



ファイル構造体を通して


数値データ


1

2

3

4

5



メモリに格納されたなら


ハードディスク内の


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ファイルをオープンモード"w"


で開き


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


数値データ

1

2

3

4

5

を書き込み


そしてクローズできました


あとは

ハードディスク内の


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


1

2

3

4

5


保存されているか確認、確認。



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


PC内で検索して


中身を確認してみると


おお


ちゃんと改行されて

数値データ

1

2

3

4

5


が きれいに1行ずつならんで保存されてる」



🌻       🌻


それでは数値データ

1

2

3

4

5


を保存し、準備が整ったところで


オープンモード"r"で


再び


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


を開いて


fscanf関数をつかって


TEN-GOGO-C-language.txtファイルに格納された

数値データ

1

2

3

4

5



メモリに格納し


さらにそれらの数値データ

1

2

3

4

5


配列に格納し


配列内に格納された


1

2

3

4

5


printf関数を使って


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


それには次のようにプログラムを記述します


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


int hairetu[5];


fscanf(fp,"%d",&hairetu[0]);

fscanf(fp,"%d",&hairetu[1]);

fscanf(fp,"%d",&hairetu[2]);

fscanf(fp,"%d",&hairetu[3]);

fscanf(fp,"%d",&hairetu[4]);


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;

}


コンパイル結果(EAZY IDECの場合)

ビルド結果(Visual Studioの場合)


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

1

2

3

4

5


🌻  🌻  🌻



ソーラー「コマンドプロンプト画面に

1

2

3

4

5


表示できてるね。


ねえ😊きみ、


数値データ

1

2

3

4

5


これ、どのような仕組みでTEN-GOGO-C-language.txtファイルから

数値データ

1

2

3

4

5

がとりだされ

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

1

2

3

4

5


が表示されているの?」




🌻   🌻

このプログラムを詳しくみていく?



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


に保存されている


数値データをコマンドプロンプト画面に表示する


このプログラムでは


まず


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


に保存されている数値データは


ファイル構造体を通して


コンピュータのメモリに格納されます。


ファイルポインタ変数宣言とfopen関数の設定


FILE *fp;

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


が実行されると


ファイル構造体が作製され


ファイルポインタ変数fpを使って


TEN-GOGO-C-language.txtファイル内に保存されているデータを


メモリに読み取ることができるようになります


int hairetu[5];

おこなうことにより


ハードディスクのファイルからメモリに読み取った


数値データ

1

2

3

4

5


格納するための


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


用意します。


fscanf(fp,"%d",&hairetu[0]);

fscanf(fp,"%d",&hairetu[1]);

fscanf(fp,"%d",&hairetu[2]);

fscanf(fp,"%d",&hairetu[3]);

fscanf(fp,"%d",&hairetu[4]);


が実行されると


ファイル構造体を通して


コンピュータのメモリに


数値データ

1

2

3

4

5

格納されます


その後


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


数値データ

1

2

3

4

5


が格納されます😊



ここで

配列宣言

int hairetu[5];を行い


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

を5つ用意しました。


fscanf関数をつかって


メモリに格納された


TEN-GOGO-C-language.txtファイル内の数値データ

1

2

3

4

5

1行ずつ改行されて


TEN-GOGO-C-language.txtファイルに保存されています。


そしてメモリに取り込まれたこれらの数値が


配列に格納される際


1

2

3

4

5

が収められている


1行ごとに


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

に格納されていくシステムとなっています


ハードディスクのファイルの


1行目の数値1が


hairetu[0]にとりこまれたなら


同時に


2行目の数値2が


hairetu[0]には取り込まれたりはしないのです


そうして


配列変数に


hairetu[0]=1

hairetu[1]=2

hairetu[2]=3

hairetu[3]=4

hairetu[4]=5


と格納された数値は


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


が実行されると


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


1

2

3

4

5


と表示されます


それでは次に


fscanf関数の仕組みを


今のプログラムの命令文


fscanf(fp,"%d",&hairetu[0]);

fscanf(fp,"%d",&hairetu[1]);

fscanf(fp,"%d",&hairetu[2]);

fscanf(fp,"%d",&hairetu[3]);

fscanf(fp,"%d",&hairetu[4]);


をつかって説明してみます。



fscanf関数の第1引数にはファイルポインタ変数fpが記述されています。


fpは


ファイルポインタ変数宣言とfopen関数の設定

FILE *fp;

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


がおこなわれたときのファイルポインタ変数fpです。


fscanf関数の第1引数に


ファイルポインタ変数宣言により


作製されたファイルポインタ変数fpを記述しなければ


fscanf関数をつかって


TEN-GOGO-C-language.txtファイルに格納されている数値データ

1

2

3

4

5


メモリに格納したのち


配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

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



fscanf(fp,"%d",&hairetu[0]);


のfpを


fscanf(sp,"%d",&hairetu[0]);


のように


spと記述してしまうと


Visual Studioの場合


エラー (アクティブ) E0020 識別子 "sp" が定義されていません


ビルドエラーが生じます。


spはファイルポインタ変数宣言されていないので


コンパイラはspが何のことなのか判断できないので


機械語に翻訳できないというわけです


fscanf(fp,"%d",&hairetu[0]);

fscanf(fp,"%d",&hairetu[1]);

fscanf(fp,"%d",&hairetu[2]);

fscanf(fp,"%d",&hairetu[3]);

fscanf(fp,"%d",&hairetu[4]);


が実行されると


まず


ファイル構造体をとおして


TEN-GOGO-C-language.txtファイルに格納されている

数値データ

1

2

3

4

5


コンピュータのメモリに格納されます



🌻さてさて


第2引数


"%d"は


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


格納されているTEN-GOGO-C-language.txtファイルの整数値データを



int


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

に格納するために記述されています


int a;


scanf("%d",&a);


が実行されると


ユーザーから与えられた整数値はint型の変数aに格納されましたね。


scanf関数をつかって


整数値データをint型の変数に格納するには


%d出力変換指定子が用いられるというルールがあります


ですので


整数値データをint型の変数aに格納するので


scanf("%d",&a);


には


%d出力変換指定子が用いられています。


それと同様に


整数値データをint型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


に格納するので


fscanf(fp,"%d",&hairetu[0]);

fscanf(fp,"%d",&hairetu[1]);

fscanf(fp,"%d",&hairetu[2]);

fscanf(fp,"%d",&hairetu[3]);

fscanf(fp,"%d",&hairetu[4]);


の第2引数には


%d出力変換指定子が用いられています。

🌼




🌻

ハードディスクの

TEN-GOGO-C-language.txtファイルに保存されている数値データが


実数値

1.1

1.2

1.3

1.4

1.5

なら


それらの数値を格納するために


配列宣言

int hairetu[5];


でなく

配列宣言

float hairetu[5];

をおこない


float型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

を作製します


実数値データをfloat型の配列変数に格納するので


%d出力変換指定子ではなく


%f出力変換指定子を


fscanf関数の第2引数に用いて


次のように記述します


fscanf(fp,"%f",&hairetu[0]);

fscanf(fp,"%f",&hairetu[1]);

fscanf(fp,"%f",&hairetu[2]);

fscanf(fp,"%f",&hairetu[3]);

fscanf(fp,"%f",&hairetu[4]);


これで


float型の配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


ハードディスクの

TEN-GOGO-C-language.txtファイルに保存されている実数値


1.1

1.2

1.3

1.4

1.5


を格納することができます


fscanf関数の


第3引数である


&hairetu[0]

&hairetu[1]

&hairetu[2]

&hairetu[3]

&hairetu[4]

などは


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


のアドレスをあらわしています


第3引数には


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

格納された


ハードディスク内のTEN-GOGO-C-language.txtファイルの数値データ


1

2

3

4

5

格納するメモリのアドレス


を記入することになっています


どう?


そうして


fscanf(fp,"%d",&hairetu[0]);

fscanf(fp,"%d",&hairetu[1]);

fscanf(fp,"%d",&hairetu[2]);

fscanf(fp,"%d",&hairetu[3]);

fscanf(fp,"%d",&hairetu[4]);

が実行されることにより


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

に数値データ

1

2

3

4

5

が格納されたのち


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

が実行されて


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


1

2

3

4

5


が表示されています。


🌼  🌼  🌼


ソーラー「?えっと


つまり


簡単に言うと


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


格納されている数値

1

2

3

4

5


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

にfscanf関数をつかって取り込み


printf関数をつかって


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

に格納されている

数値

1

2

3

4

5

をコマンドプロンプト画面に表示するという仕組みなのかな」


🌻

そのとおり😊


ご名答、ソーラーさん


🌼


ソーラー 「ところで なぜ


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


数値12345でなく


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


をつかって


         🍓”1行ずつ改行して”🍓


(ただいま🍓マーク大サービス中)


1

2

3

4

5


とかきこんだの?」


🌻


そこはいいポイントを・・・


それはね


先程も述べたように


ハードディスク内のファイルTEN-GOGO-C-language.txt内のデータは


1行ごとに管理されていて


fscanf関数はその管理された1行ごとに


書き込まれているデータを


配列変数


hairetu[0]に最初の1行分のデータ

hairetu[1]に次の2行目の1行分のデータ

hairetu[2]に次の3行目の1行分のデータ

hairetu[3]に次の4行目の1行分のデータ

hairetu[4]に次の5行目の1行分のデータ


を格納していく。


だから

次のプログラムのように


#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",12345);


fclose(fp);

return 0;

}


fprintf関数を使って


fprintf(fp,"%d\n",12345);



数値データ12345を


ハードディスク内のTEN-GOGO-C-language.txtファイルの1行の中に


データを保存したとするね


そして


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


数値データ


12345


をprintf出力表示する


次のようなプログラムを実行すると


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


int hairetu[1];


fscanf(fp,"%d",&hairetu[0]);


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


fclose(fp);

return 0;

}


コンパイル後


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


12345


と表示されます。



このプログラムでは


まず


ファイルポインタ変数宣言とfopen関数の設定

FILE *fp;

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

をおこない


ファイル構造体を通して


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


ハードディスクのファイルに保存されている数値データ


12345を格納しています


そして


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


格納されている数値データ12345を


fscanf(fp,"%d",&hairetu[0]);


を実行することにより


数値データ12345を


配列宣言 int hairetu[1];


により作製された


配列変数hairetu[0]に格納し


printf関数をつかって


hairetu[0]に格納された数値データ12345を


コマンドプロンプト画面に表示しています。


もとから数値データ12345



fprintf(fp,"%d\n",12345);


により


ファイルの1行目の中に格納されていたので


コンパイル結果は

1

2

3

4

5

と5行にわかれて表示されることはなく


1行の内に

12345と表示されます。


ハードディスク内の


自作ファイルのデータ管理が1行ごとに行われているのを


確認するために


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

を実行して


数値データ

1

2

3

4

5


1行ずつ改行して


ハードディスクのTEN-GOGO-C-language.txtファイルに格納してもらった😊


というわけです。


ソーラー「へぇ~


一見するとハードディスク内の自作ファイルの中身は


何もデータが保存されていないとき


一面 真っ白い画面だけど 


保存されたデータは


1行ずつ管理されてるんだ。


ほんとう


詳しく説明ありがとう 


🌻

どういたしまして ソーラーさん


みなさん


わかってきたかな?


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

作者を応援しよう!

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

応援したユーザー

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