天国にいけるC言語入門 ヘキサ構造体 ver5.2130
fseek関数を用いてバイナリファイルからデータの読み込み開始位置を指定してからデータを読みこんでみましょう 読み取り基準位置がSEEK_CURの場合
fseek関数を用いてバイナリファイルからデータの読み込み開始位置を指定してからデータを読みこんでみましょう 読み取り基準位置がSEEK_CURの場合
アレサ 「今度はfseek関数で
第3引数にSEEK_CURを使い
fseek(fp,sizeof(int),SEEK_CUR)と記述された場合について
プログラムがどのような動作をしていくかみていきます。」
ソーラー「fseek関数の 第3引数がSEEK_CURと記述された場合の
解説スタートしま~す。
カメラさんこっち、こっち
真紅の美女がここにいます。
それではよろしくお願いしま~~~す。😊」
アレサ「はいっ ソーラーさん
実はSEEK_CURシステムは簡単です。
では
また 準備として
数値データ
1
2
3
4
5
6
7
を
バイナリデータとして
バイナリファイルに
セッティングするところから
はじめます。
まずはいつもどおり
数値データ
1
2
3
4
5
6
7
を
fwrite関数を使ってバイナリファイルに保存してみます
そのプログラムは次のようになります。
#pragma warning(disable: 4996)
#include <stdio.h>
int main (void){
FILE *fp;
fp=fopen("TEN-GOGO-C-language.bin","wb");
if(fp==NULL){
printf("ファイルオープンに失敗しましたよ~ん\n");
return -1;}
else printf("Hello!ファイルオープンに成功しましたよ~ん\n");
int hairetu[]={1,2,3,4,5,6,7};
fwrite(&hairetu[0],sizeof(int),1,fp);
fwrite(&hairetu[1],sizeof(int),1,fp);
fwrite(&hairetu[2],sizeof(int),1,fp);
fwrite(&hairetu[3],sizeof(int),1,fp);
fwrite(&hairetu[4],sizeof(int),1,fp);
fwrite(&hairetu[5],sizeof(int),1,fp);
fwrite(&hairetu[6],sizeof(int),1,fp);
fclose(fp);
return 0;
}
コンパイル結果
Hello!ファイルオープンに成功しましたよ~ん
アレサ「ファイルオープンに成功しました💖
そして
fp=fopen("TEN-GOGO-C-language.bin","wb");
のオープンモード"wb"と
fwrite関数のはたらきにより
数値データ
1
2
3
4
5
6
7
を
バイナリファイルである
TEN-GOGO-C-language.binに保存できました。」
ソーラー「いいよ~😊その調子」
アレサ
「では次に
fseek(fp,sizeof(int),SEEK_SET);
を使って
読み取り開始位置を図で示されるように
2を格納している2行目の前の位置😊😊😊😊😊😊😊に指定し
最初の位置_________SEEK_SET(読み取り基準位置)
1 sizeof(int)=4バイト
______________😊😊😊😊😊😊😊
2 sizeof(int)=4バイト
______________
3 sizeof(int)=4バイト
______________
4 sizeof(int)=4バイト
______________
5 sizeof(int)=4バイト
______________
6 sizeof(int)=4バイト
______________
7 sizeof(int)=4バイト
最後の位置_________SEEK_END
数値2からfread関数を使って
配列宣言
int hairetu[3];
により生成された
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
に
数値
2
3
4
を
格納してみます
そして
hairetu[0]
hairetu[1]
hairetu[2]
に格納された
数値データ
2
3
4
を
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
をおこない
コマンドプロンプト画面にprintf出力表示してみます
そのプログラムは次のようになります。」
#pragma warning(disable: 4996)
#include <stdio.h>
int main (void){
FILE *fp;
fp=fopen("TEN-GOGO-C-language.bin","rb");
if(fp==NULL){
printf("ファイルオープンに失敗しましたよ~ん\n");
return -1;}
else printf("Hello!ファイルオープンに成功しましたよ~ん\n");
int hairetu[3];
fseek(fp,sizeof(int),SEEK_SET);
fread(&hairetu[0],sizeof(int),1,fp);
fread(&hairetu[1],sizeof(int),1,fp);
fread(&hairetu[2],sizeof(int),1,fp);
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
fclose(fp);
return 0;
}
コンパイル結果
Hello!ファイルオープンに成功しましたよ~ん
2
3
4
アレサ「このように
fseek(fp,sizeof(int),SEEK_SET);
と
fseek関数の
第2引数に
sizeof(int)=4
第3引数に
SEEK_SET
を記述することにより
👇の図のように
最初の位置_________SEEK_SET(読み取り基準位置)
1 sizeof(int)=4バイト
______________😊😊😊😊😊😊😊
2 sizeof(int)=4バイト
______________
3 sizeof(int)=4バイト
______________
4 sizeof(int)=4バイト
______________
5 sizeof(int)=4バイト
______________
6 sizeof(int)=4バイト
______________
7 sizeof(int)=4バイト
最後の位置_________SEEK_END
読み取り開始位置を2行目の前の😊😊😊😊😊😊😊に指定することができました。
そして
fread関数をもちいて
2から
2
3
4
を
hairetu[0]
hairetu[1]
hairetu[2]
に格納し
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
により
コマンドプロンプト画面に
2
3
4
を
表示することができました。」
ソーラー「ここからだね🌞🌞🌞🌞🌞🌞🌞🌞」
アレサ「はいっ もちろんですの。
ではまいります
『
『
『
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
ソーラー「絶好調だね。アレサ
ここで・・・」
アレサ 「ここで次は
数値
2
3
4
につづいて
数値
5
6
7
をfread関数を使って配列に格納していきたいのですが・・・」
ソーラー「
新たに5から読み取りを開始し
5
6
7
とデータを配列に格納したいんだね。」
アレサ「ここでSEEK_CURが登場します。
さきほど
数値
2
3
4
がfread関数を使って配列に格納されました。
このとき
最後に読み取られた4を格納している4行目の後
5行目の前の位置が
SEEK_CURの位置となります
最初の位置_________SEEK_SET
1 sizeof(int)=4バイト
______________
2 sizeof(int)=4バイト
______________
3 sizeof(int)=4バイト
______________
4 sizeof(int)=4バイト
______________😊SEEK_CUR😊
5 sizeof(int)=4バイト
______________
6 sizeof(int)=4バイト
______________
7 sizeof(int)=4バイト
最後の位置_________SEEK_END
つまり
😊SEEK_CUR😊の位置は
SEEK_SETや
SEEK_ENDのように
はじめから
決まっているのでなく
最後に読み取られたデータを格納している行の後が
😊SEEK_CUR😊の位置となります。
例えば
今
バイナリファイル内のデータ
1
2
3
4
5
6
7
のうち
5だけを
fread関数で
読み込んで用意した配列に格納したとします。
すると
😊SEEK_CUR😊の位置は
図で示される位置になります。
最初の位置_________ <<<SEEK_SET
1 int(4バイト)
______________
2 int(4バイト)
______________
3 int(4バイト)
______________
4 int(4バイト)
______________
5 int(4バイト)
______________😊SEEK_CUR😊の位置
6 int(4バイト)
______________
7 int_(4バイト)
最後の位置_________<<<SEEK_END
つまり
今の場合は
最後にfread関数を使って数値5を読み取り、配列に格納したことになるのですが
😊SEEK_CUR😊の位置は
その最後に配列に読み取った数値5を
格納している5行目のあとに移動します。
そしてまた新たに
fread関数で
数値1だけを読み取り配列に格納したならば
😊SEEK_CUR😊の位置は図で示される位置となります
最初の位置_________ <<<SEEK_SET
1 int(4バイト)
______________😊SEEK_CUR😊の位置
2 int(4バイト)
______________
3 int(4バイト)
______________
4 int(4バイト)
______________
5 int(4バイト)
______________
6 int(4バイト)
______________
7 int_(4バイト)
最後の位置_________<<<SEEK_END
このように
最後にfread関数によって読み込まれ配列に格納された数値1を
格納している行の後に
😊SEEK_CUR😊の位置が移動するのです。
また新しくプログラムを構成し
fread関数を用い
2
3
4
をバイナリファイルから読み込み
配列に格納したなら
図の位置に
😊SEEK_CUR😊の位置は移動します
最初の位置_________ <<<SEEK_SET
1 int(4バイト)
______________
2 int(4バイト)
______________
3 int(4バイト)
______________
4 int(4バイト)
______________😊SEEK_CUR😊の位置
5 int(4バイト)
______________
6 int(4バイト)
______________
7 int_(4バイト)
最後の位置_________<<<SEEK_END
😊SEEK_CUR😊の位置は
最後にfread関数によって読み込まれた4を格納している
4行目の後
5行目の前に移動しています。
ソーラー「なんと😊SEEK_CUR😊の位置って
いろいろかわってくるんだね。」
アレサ「はいっ
そして
😊SEEK_CUR😊の位置から
ファイルデータを読み込みたいときには
fseek関数の第3引数に
SEEK_CURをもちいます
その際は
データを😊SEEK_CUR😊の位置から
ずらして読み込む必要がないので
fseek関数の第2引数の値を0にします。
つまり 次の命令文のように記述するのでなく
fseek(fp,sizeof(int),SEEK_CUR);
SEEK_CURの位置から読み取りをすぐ開始するように
sizeof(int)の値を0にし
fseek(fp,0,SEEK_CUR);と記述します。
fseek(fp,sizeof(int),SEEK_CUR);
と読み込み開始位置を指定すると
😊SEEK_CUR😊の位置から sizeof(int)1つ分
後ろのデータから読み込みを開始するようになります。
それでは
さきほどのプログラム
👇
#pragma warning(disable: 4996)
#include <stdio.h>
int main (void){
FILE *fp;
fp=fopen("TEN-GOGO-C-language.bin","rb");
if(fp==NULL){
printf("ファイルオープンに失敗しましたよ~ん\n");
return -1;}
else printf("Hello!ファイルオープンに成功しましたよ~ん\n");
int hairetu[3];
fseek(fp,sizeof(int),SEEK_SET);
fread(&hairetu[0],sizeof(int),1,fp);
fread(&hairetu[1],sizeof(int),1,fp);
fread(&hairetu[2],sizeof(int),1,fp);
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
fclose(fp);
return 0;
}
コンパイル結果
Hello!ファイルオープンに成功しましたよ~ん
2
3
4
に
命令文
fseek(fp,0,SEEK_CUR);
fread(&hairetu[0],sizeof(int),1,fp);
fread(&hairetu[1],sizeof(int),1,fp);
fread(&hairetu[2],sizeof(int),1,fp);
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
を追加して
2
3
4
につづいて
5
6
7
が
fread関数によって読み込まれ
コマンドプロンプト画面に
表示されるよう
プログラムを作成、コンパイルしてみますね。😊
そのプログラムは次のようになります。」
#pragma warning(disable: 4996)
#include <stdio.h>
int main (void){
FILE *fp;
fp=fopen("TEN-GOGO-C-language.bin","rb");
if(fp==NULL){
printf("ファイルオープンに失敗しましたよ~ん\n");
return -1;}
else printf("Hello!ファイルオープンに成功しましたよ~ん\n");
int hairetu[3];
fseek(fp,sizeof(int),SEEK_SET);/*読み取り開始位置を1行目の後 2行目の前に指定しました*/
fread(&hairetu[0],sizeof(int),1,fp);
fread(&hairetu[1],sizeof(int),1,fp);
fread(&hairetu[2],sizeof(int),1,fp);
/*この時点で😊SEEK_CUR😊の位置は
4行目の後 5行目の前に移動しています。*/
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
fseek(fp,0,SEEK_CUR);
fread(&hairetu[0],sizeof(int),1,fp);
fread(&hairetu[1],sizeof(int),1,fp);
fread(&hairetu[2],sizeof(int),1,fp);
/*ですのでfseek(fp,0,SEEK_CUR);
により
😊SEEK_CUR😊の位置である
4行目の後 5行目の前が
読み取り開始位置に指定されます。
つまり
fread関数を使って
数値5から
数値の読み取り、配列への格納が始まります
*/
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
fclose(fp);
return 0;
}
アレサ「このプログラムをコンパイルすると
コンパイル結果
Hello!ファイルオープンに成功しましたよ~ん
2
3
4
5
6
7
となります。」
ソーラー「やったね、アレサ
すごいなあ
素敵なお嬢さん」
アレサ「このプログラムでは
配列int hairetu[3]内の
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
に
まず最初に
fread関数によって読み込まれた
バイナリファイルの数値データ
2
3
4
が
hairetu[0]=2
hairetu[1]=3
hairetu[2]=4
と格納され
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
により
コマンドプロンプト画面に
2
3
4
がprintf出力表示されていきます。
この時点で
😊SEEK_CUR😊の位置は
最後にfread関数によって読み込まれた4を格納している
4行目の後 5行目の前に移動しています。
ですから
fseek(fp,0,SEEK_CUR);
が行われると
fread関数の読み込み開始位置は
4行目の後
数値5を格納している
5行目の前になります。
ですので
fread(&hairetu[0],sizeof(int),1,fp);
fread(&hairetu[1],sizeof(int),1,fp);
fread(&hairetu[2],sizeof(int),1,fp);
により
読み取りが開始されると
5
6
7
が
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
に
hairetu[0]=2
hairetu[1]=3
hairetu[2]=4
から
hairetu[0]=5
hairetu[1]=6
hairetu[2]=7
へと上書きされ
格納されていきます
そして
printf("%d\n",hairetu[0]);
printf("%d\n",hairetu[1]);
printf("%d\n",hairetu[2]);
により
コマンドプロンプト画面に
2
3
4
に続いて
5
6
7
が
printf出力表示されていきます
その結果コンパイル結果は
Hello!ファイルオープンに成功しましたよ~ん
2
3
4
5
6
7
となります。
ここで
int hairetu[3];
により
生成された
hairetu[0]
hairetu[1]
hairetu[2]
は
fseek(fp,sizeof(int),SEEK_SET);
fread(&hairetu[0],sizeof(int),1,fp);
fread(&hairetu[1],sizeof(int),1,fp);
fread(&hairetu[2],sizeof(int),1,fp);
で数値
2
3
4
を格納するときと
fseek(fp,0,SEEK_CUR);
fread(&hairetu[0],sizeof(int),1,fp);
fread(&hairetu[1],sizeof(int),1,fp);
fread(&hairetu[2],sizeof(int),1,fp);
で数値
5
6
7
を格納するとき
の両方で使用されています
まず
hairetu[0]
hairetu[1]
hairetu[2]
に
hairetu[0]=2
hairetu[1]=3
hairetu[2]=4
と
数値が格納された状態から
hairetu[0]=5
hairetu[1]=6
hairetu[2]=7
と上書きされるかたちで
数値
5
6
7
が格納されているのですね。」
ソーラー 「数値をprintf出力表示するのに
同じ配列
int hairetu[3];をつかっているんだね。
このような優雅な
配列
の使い方があるんだね。
これでfseek関数の第3引数に
SEEK_CURを使った場合
fread関数を使って
バイナリファイルのどの位置のデータから
読み込みが開始されるのかがわかったね」
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます