天国にいけるC言語入門 ヘキサ構造体 ver5.2130
fseek関数を用いてデータの読み込み開始位置を指定してバイナリファイルからからデータを読みこんでみましょう 読み取り基準位置がSEEK_ENDの場合
fseek関数を用いてデータの読み込み開始位置を指定してバイナリファイルからからデータを読みこんでみましょう 読み取り基準位置がSEEK_ENDの場合
アレサ 「今度はfseek関数で
第3引数にSEEK_ENDが用いられた場合
プログラムがどのような動作をしていくかみていきます。
まずはいつもどおり
数値
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に保存しました。
そして
SEEK_ENDの位置が
どこにあたるかを
今、
バイナリファイルに格納されている
バイナリデータ
1
2
3
4
5
6
7
をもちいて説明いたします。」
ソーラー「では再び、お願い💖」
アレサ「はい😊
では、わかりやすく
SEEK_ENDの位置にあたる場所を図で表してみます。
図でみると
数値データ7の後の最後の位置が
SEEK_ENDの位置にあたります。」
図
最初の位置_________ <<<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🌞
アレサ 「SEEK_ENDは
最後のデータである7を格納している7行目のすぐ後の
最後の位置を表しています。」
ソーラー「は~い」
アレサ「ですから
fseek(fp,読み込み開始位置と読み取り基準となる位置の差(読み取り基準となる位置からどれくらい離れているかをあらわす。),読み取り基準となる位置);
が
fseek(fp,-2*sizeof(int),SEEK_END);
と記述された場合は
第3引数の読み取り基準となる位置は
SEEK_ENDに設定されています。
次は第2引数を設定してみます。
第3引数の読み取り基準となる位置を
SEEK_ENDと設定した場合
fseek関数の第2引数は
次の例のように記述します。
例1.fseek(fp,-sizeof(int),SEEK_END)
例2.fseek(fp,-2*sizeof(int),SEEK_END)
例3.fseek(fp,-3*sizeof(int),SEEK_END)
例4.fseek(fp,-4,SEEK_END)
例5.fseek(fp,-8,SEEK_END)
などなど・・・
このように
第3引数の読み取り基準となる位置を
SEEK_ENDと設定した場合
SEEK_ENDから遡って
読み取り開始位置が指定されるため
第2引数にはマイナスの数値が記述されることになります
ですので
sizeof(int)には-2*や-3*などのマイナス数値がかけられています
ここで
-2*sizeof(int)=-8
-3*sizeof(int)=-12
を表しています
そしてSEEK_SETのときと同じように
sizeof(int)はint型のデータ格納容量4バイトの
4
を表し
sizeof(int)は4
2*sizeof(int)は8
3*sizeof(int)は12をあらわしています。
fseek関数の第2引数が-5*sizeof(int)となった場合
どのように読み込み開始位置が指定されるのかを
みていきましょう。
fseek(fp,-5*sizeof(int),SEEK_END);ならば
この命令文は
最後の位置SEEK_ENDからsizeof(int) 5個分の幅ほど前の位置を
読み取り開始位置に指定することを表しています。
図で示すなら😊😊😊😊😊😊😊の位置が
読み取り開始位置に指定されています。
最初の位置_________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
ソーラー「👆このsizeof(int)=4バイトの容量を持つ
1行ごとに
数値
1
2
3
4
5
6
7
が
1つずつ格納されているのは先程のエピソードと同じわけなんだ」
アレサ「そうなんです。
数値
1
2
3
4
5
6
7
は
sizeof(int)=4バイトの容量を持つ1行に
1つずつ格納されています
ですので
fseek(fp,-5*sizeof(int),SEEK_END);
と表記し
数値7が格納されている行のすぐ後の
最後の位置にあたるSEEK_ENDから
sizeof(int) 5個分の幅,前の位置を
読み取り開始位置😊😊😊😊😊😊😊に指定すると
数値3が格納されている行の前の位置が
読み取り開始位置😊😊😊😊😊😊😊となります。
例2.fseek(fp,-6*sizeof(int),SEEK_END);
の命令文では
最後の位置にあたるSEEK_ENDから
sizeof(int) 6個分の幅,前の位置を
読み取り開始位置に指定しています。
図で示すなら😊😊😊の位置が
読み取り開始位置😊😊😊に指定されています。」
最初の位置_________SEEK_SET
1行目 int(4バイト)
______________読み取り開始位置😊😊😊
2行目 int(4バイト)
______________
3行目 int(4バイト)
______________
4行目 int(4バイト)
______________
5行目 int(4バイト)
______________
6行目 int(4バイト)
______________
7行目 int(4バイト)
最後の位置_________SEEK_END
ソーラー「今度はSEEK_ENDが
読み取り基準の位置になったわけなんだね」
アレサ「はい、そして実際にfseek関数を使って
バイナリファイル内での
データ読み取り開始位置を指定してから
fread関数を使い
データを
読み取っていきたいとおもいます。
ここでは
fseek(fp,-6*sizeof(int),SEEK_END);を
つかって
👇の図で表されているように
読み取り開始位置😊😊😊😊😊を2行目の前に指定します。
最初の位置_________SEEK_SET
1 int(4バイト)
______________読み取り開始位置😊😊😊😊😊
2 int(4バイト)
______________
3 int(4バイト)
______________
4 int(4バイト)
______________
5 int(4バイト)
______________
6 int(4バイト)
______________
7 int(4バイト)
最後の位置_________SEEK_END
では読み取り開始位置😊😊😊😊😊を
2を格納している2行目の前に指定して
2から
2
3
4
と数値データを
バイナリファイルから読み込んで
コマンドプロンプト画面に表示してみたいと思います。
まずはいつもどおり
数値
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;
}
コンパイル結果
(EAZY IDECの場合)
(Visual Studioの場合)
Hello!ファイルオープンに成功しましたよ~ん
アレサ「ファイルオープンに成功💖
数値データ
1
2
3
4
5
6
7
をバイナリデータに変換して
バイナリファイルに格納できました。
では
fseek(fp,-6*sizeof(int),SEEK_END);
を使って
読み取り開始位置を2の前に指定して
数値
2
3
4
をバイナリファイルからよびだしてみます。
そのプログラムは次のようになります
#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,-6*sizeof(int),SEEK_END);
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
ソーラー「これも、成功している。😊
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
に
2からデータが
読み込まれ格納されているね。」
アレサ 「このように
配列hairetuの
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
には
バイナリファイルからの数値データが
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
と表示されています」
ソーラー 「めでたし、めでたし
なんかこれってCDプレーヤーでいうところの
スキップ再生にとてもよく似てるね
fseek関数の第2引数がsizeof(int)のように
正の数なら
SEEK_SETの位置からあとの位置へスキップしてデータ読み取りを開始
fseek関数の第2引数が-6*sizeof(int)のように
負の数なら
SEEK_ENDの位置から前へスキップしてデータ読み取りを開始
しているからね。」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます