天国にいけるC言語入門 ヘキサ構造体 ver5.2130
同じプログラム内で fprintf関数を使って保存された数値を fscanf関数を使って配列に取り込むにはデータを保存後1度ファイルを閉じて書き込みモードを解除する必要があります。
fclose関数にはファイルを閉じるという機能のほかに ファイルの書き込みモード、読み込みモードを解除するという面も持っています
同じプログラム内で fprintf関数を使って保存された数値を fscanf関数を使って配列に取り込むにはデータを保存後1度ファイルを閉じて書き込みモードを解除する必要があります。
ソーラー 「オープンモード"w+"の読み取り機能に関しては
なんか 微妙な考察結果となったね」
🌞ははは🌞
🌞ははは🌞
ソーラー
「それではっっ
ちょっと応用をきかせて
まっさらで何も保存されていない
TEN-GOGO-C-language.txtファイルに
fprintf関数を使って
数値
1
2
3
4
5
を
保存し
保存した、そのすぐ後に fscanf関数を使って
TEN-GOGO-C-language.txtファイルに
fprintf関数を使って
保存されたばかりの数値
1
2
3
4
5
を
配列の配列変数にとりこみ
配列の配列変数に格納された
1
2
3
4
5
を
コマンドプロンプト画面にprintf出力表示できるかどうか
ためしてみよぉぉぉぉ」
🌻みよぉぉぉぉおぉぉっ
ソーラー「まずは恒例の
次のプログラムを実行して
TEN-GOGO-C-language.txtファイルを
まっさら~
何もデータが保存されていない状態にしてみます。
#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");
fclose(fp);
return 0;
}
コンパイル結果
Hello!ファイルオープンに成功しましたよ~ん
ソーラー「PC内検索で
実際に
TEN-GOGO-C-language.txtファイル
の中身を調べてみると
もろに美しい空白が広がっている
清々しいね。
準備完了🌞
そして次に
そのまっさらな
TEN-GOGO-C-language.txtファイルに
fprintf関数を使って
数値
1
2
3
4
5
を
保存し
そのすぐ後に fscanf関数を使って
TEN-GOGO-C-language.txtファイルに
保存されたばかりの数値
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","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);
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;
}
コンパイル結果
Hello!ファイルオープンに成功しましたよ~ん
9
2
1703760
1964398416
1703808
(この値はコンピュータのメモリの使用状況によって異なってきます。)
ソーラー「
なぜぇ
数値
1
2
3
4
5
を
fprintf関数をつかって
TEN-GOGO-C-language.txtファイルに
格納したはずなのに
fscanf関数をつかって
TEN-GOGO-C-language.txtファイルに格納された
数値
1
2
3
4
5
を
コマンドプロンプト画面にprintf出力表示したら
9
2
1703760
1964398416
1703808
(この値はコンピュータのメモリの使用状況によって異なってきます。)
になる???????
なぜ??
??」
🌻 🌻 🌻
くすっ
どうやら
fprintf関数が使われて
TEN-GOGO-C-language.txtファイルは
書き込みのみできる状態となっているのだけど
ファイルを閉じて
書き込みのみできる状態を解除しないから
ファイルからデータを読み込む
fscanf関数が機能していない
だから
fscanf関数をつかって
配列宣言
int hairetu[5];
により
生成された配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
に
ハードディスク内に保存された数値データ
1
2
3
4
5
を格納することができず
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
は初期化されないということになるわけだね
そうして
コンパイル結果は
配列変数が初期化されていないときに
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
に
格納されている数値
9
2
1703760
1964398416
1703808
(この値はコンピュータのメモリの使用状況によって異なってきます。)
が
printf出力表示されたんだね
🌻 🌻
ソーラー「そうだね
最終的には
このプログラムは
プログラムの最後で
fclose(fp);
が行われて
TEN-GOGO-C-language.txtファイルの書き込み状態が解除され
TEN-GOGO-C-language.txtファイルは閉じられてる状態になってるね。
そういえば
TEN-GOGO-C-language.txtファイルにデータが保存されることと
fclose(fp);
によって
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);
によって
ちゃんと
数値データ
1
2
3
4
5
が
TEN-GOGO-C-language.txtファイルに
格納されたかどうかを調べてみよう🌞
PC内検索でTEN-GOGO-C-language.txtファイルを
検索してみると・・・
おお やっぱりかな
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);
によって
1
2
3
4
5
が保存されてるね」
🌻あっ ほんとだ🌻
ソーラー「そして
TEN-GOGO-C-language.txtファイルが閉じられることと
TEN-GOGO-C-language.txtファイルにデータが保存されることとは
関係ないのでした。
fclose(fp);
はファイルが開かれている状態を解除するために
あるのです
っていうのも
なんか
おもいだしちゃったな
🌻そう、そうだった🌻
ソーラー「どうやったら??
同じプログラム内で
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);
を実行して
TEN-GOGO-C-language.txtファイルに
数値
1
2
3
4
5
を
保存した直後
fscanf関数を使って
TEN-GOGO-C-language.txtファイルに格納された
それらの
数値
1
2
3
4
5
を
配列宣言
int hairetu;
により生成された
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
に格納し
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
に格納された
数値
1
2
3
4
5
を
printf出力表示できるのかな・・・
つまり
fprintf関数を使うことにより
TEN-GOGO-C-language.txtファイル
を
fscanf関数をつかって
格納されたデータを
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
に格納できる
変更したいというわけなんだね。
fprintf関数を使うことにより
書き込みのみできる状態となった
TEN-GOGO-C-language.txtファイル
に保存されたデータは
その書き込みのみできる状態のままでは
fscanf関数をつかって
読み取りができない。
その
書き込みのみできる状態から
読み込みのみできる状態に
変更するには?」
🌻は~い\(^o^)/ 🌻
ソーラー「わっ 君、元気がいいね」
🌻こんなんでどうかな?
fprintf関数により
TEN-GOGO-C-language.txtファイル
に保存されたデータ
1
2
3
4
5
を
fscanf関数をつかって配列に格納するには
fclose(fp);
を実行して
1度、
fprintf関数を使用することにより
書き込みのみできる状態に開かれている
TEN-GOGO-C-language.txtファイルの状態を
解除する必要があるんだよね。
fclose(fp);
を実行して
書き込みのみできる状態に開かれている
TEN-GOGO-C-language.txtファイルの状態を
解除したあと
fscanf関数を使用すると
書き込みのみできる状態から読み込みのみできる状態に
TEN-GOGO-C-language.txtファイルを開くことができるんだ
だから
今のプログラムの
👇
#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);
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!ファイルオープンに成功しましたよ~ん
9
2
1703760
1964398416
1703808
(この値はコンピュータのメモリの使用状況によって異なってきます。)
👆
を次のように書き換えればいいことに
なります。
#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);
/*TEN-GOGO-C-language.txtが書き込みのみできる状態
に開かれているのを解除しました*/
FILE *fp;
fp=fopen("TEN-GOGO-C-language.txt","a+");
if(fp==NULL){
printf("ファイルオープンに失敗しましたよ~ん\n");
return -1;}
/*TEN-GOGO-C-language.txtファイルを閉じたので
そのままでは
TEN-GOGO-C-language.txtファイルに格納された数値データを
よみとることができない?
とおもい
再び
ファイルポインタ変数宣言とオープンモードの設定を行いました。
(Visual Studioをお使いの方は、
ファイルポインタ変数宣言
FILE *fp;
は記述しないでください
ビルドエラーになります
理由は後述します)*/
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;
}
コンパイル結果
Hello!ファイルオープンに成功しましたよ~ん
Hello!ファイルオープンに成功しましたよ~ん
1
2
3
4
5
👆
このプログラムのように
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
が格納された後
fclose(fp);
を行い
書き込みモード
つまり
ファイルが書き込みのみできる状態で開かれている状態を
解除しないといけないというわけなんだね。
fclose(fp);
を行うと
書き込みモードを解除できるけど
このままではファイルが閉じられたままで
読み込みができないから
ふたたび
ファイルポインタ変数宣言とfopen関数の設定
FILE *fp;
fp=fopen("TEN-GOGO-C-language.txt","a+");
(Visual Studioをお使いの方は、FILE *fp;を繰り返し記述しないでください
ビルドエラーになります
理由は後述します)
if(fp==NULL){
printf("ファイルオープンに失敗しましたよ~ん\n");
return -1;}
を行う必要があるんだね。
そして
今は
再び
読み込みも書き込みもできる
オープンモード"a+"で
TEN-GOGO-C-language.txtファイルが開かれたわけだけど
🐤オープンモード"a+"🐤
が
読み込みモードになるか書き込みモードになるかは
つまり
読み込みのみできる状態にファイルが開かれるか
書き込みのみできる状態にファイルが開かれるか
は
最初に
読み込みできるfscanf関数を使うか
書き込みできるfprintf関数を使うかによって決まるので
今度は最初に
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]);
の命令文が実行されると
オープンモード"a+"は
読み込みモードになります
つまり
読み込みのみできる状態にTEN-GOGO-C-language.txtファイルが
開かれることになります
そして
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]
に
fprintf関数によってたった今
TEN-GOGO-C-language.txtファイルに保存された
数値
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
が表示される。
ということになるんだよ~~
🌻 🌻
ソーラー「やったね!まさにそのとおり」
🌻
あははははは どう どう
ソーラーさん
🌻
ソーラー「おみごとです!
このように
🐥同じプログラム内で🐤
fprintf関数を使って保存された数値を
fscanf関数を使って配列に取り込むには、
fprintf関数を使ってファイルにデータを保存したあと
1度
fclose関数によりファイルを閉じて
書き込みモードを解除し
再びファイルを読み込みモードで
開いて
fscanf関数を使用可能状態に
する必要があります。」
🌳 🌳 🌳
プログラム中に
(Visual Studioをお使いの方は、
FILE *fp;
繰り返し記述しないでください
ビルドエラーになります)
と記述されていました
FILE *fp;
を繰り返し記述すると
Visual Studioでは
FILE *fp;が再定義されています
つまり
ファイルポインタ変数宣言が
重複して使用されていますという意味の
ビルドエラーが表示されます。
Visual Studioでは
同じ名前をつかった変数宣言を
2度おこなうことはできないのです
fclose(fp);
により
ファイルが閉じられているのに
FILE *fp;
を記述しないで
ファイルポインタ変数fpが使用できるの?
と思われる方もいるかもしれません。
ファイルポインタ変数宣言
FILE *fp;
と
fclose(fp);
は
なんの関係もなく独立している
つまり
fclose(fp);
がおこなわれても
ファイルにファイルポインタ変数fpを用いてアクセスできる状態が
閉じられるだけで
ファイルポインタ変数fpそのものが
消去されてしまうわけではありません
ですので
fclose(fp);
により
ファイルが閉じられても
ファイルポインタ変数宣言
FILE *fp;
によって
作製された
ファイルポインタ変数fpは機能しています。
ですので
FILE *fp;
を
2度実行する必要はないというわけです。
また
書き込みモードと
読み込みモードで
同じ
ファイルポインタ変数宣言
FILE *fp;
によって作製される
ファイルポインタ変数fp
が使用されても
大丈夫なの?
と思われる方もいるかもしれません。
ファイルポインタ変数宣言
FILE *fp;
により
作製された
ファイルポインタ変数fpには
ハードディスクに保存したいデータをメモリに格納するとき
また
ハードディスクのファイルデータを読み取ってメモリに保存するとき
そのメモリのアドレスが格納されます。
たとえば
ハードディスクのファイルにデータを保存する際
まず
メモリにそのデータは格納されます。
つづいて
TEN-GOGO-C-language.txtファイルデータを読み取って
メモリに格納するとき
ファイルポインタ変数fpには
そのメモリのアドレスが格納されるのですが
そのとき
ファイルポインタ変数fpには
そのメモリのアドレスが
💖上書きして💖
格納されます。
ですので
1度
ファイルポインタ変数宣言
FILE *fp;
をおこなえば
そのファイルポインタ変数に
上書きして
メモリのアドレスが書き込まれることになるので
書き込みモードと
読み込みモードで
同じ
ファイルポインタ変数fpをつかっても問題ありません
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます