第53章 低水準ファイル入出力 その4


さて、今回は前章の続きでedit_file関数を作ります。 その前に、1つだけ関数の説明をしておきます。

#include <io.h> 関数宣言のためにのみ必要 #include <stdio.h> long _lseek(int handle, long offset, int origin);

マイクロソフト以外のコンパイラでは最初のアンダスコアを取って下さい。 これは、ファイルポインタの移動のための関数です。単に、ファイルのどこ から、読み書きするかを示すものと考えて下さい。 ファイルの途中を変更するときに必要ですね。handleは _openしたとき取得できますね。originはファイルのどこを起点に するかです。

SEEK_SET ファイルの先頭 SEEK_CUR ファイルポインタのカレント位置 SEEK_END ファイルの終端

の中から選びます。 offsetはoriginから何バイト先をファイルポインタにするかを 指定します。

_lseek(hdl, 100L, SEEK_SET);

とすれば、ファイルの最初から100バイト先をファイルポインタとする という意味になります。 それでは、さっそくedit_file関数を作ってみましょう。

int edit_file(void) { char no[8], name[21], address[41], chk[4]; if (strcmp(file_name, " ") == 0) { printf("ファイル名="); gets(file_name); } hdl = _open(file_name, _O_RDWR); if (hdl == -1) { printf("エラーです\n"); exit(-1); } while(1) { printf("\n修正したいデータno="); gets(no); _lseek(hdl, 60L * (atoi(no) - 1) , SEEK_SET); _read(hdl, name, 20); _read(hdl, address, 40); printf("修正するデータは\n"); printf("[%2d]%s\n", atoi(no), name); printf(" %s\n", address); printf("これでよいですか(y/n)="); gets(chk); if (chk[0] == 'y' || chk[0] == 'Y') { memset(name, ' ', sizeof(name)); memset(address, ' ', sizeof(address)); printf("氏名="); gets(name); printf("住所="); gets(address); _lseek(hdl, 60L * (atoi(no) - 1), SEEK_SET); _write(hdl, name, 20); _write(hdl, address, 40); } printf("もう1件修正しますか(y/n)="); gets(chk); if (chk[0] == 'n' || chk[0] == 'N') break; } _close(hdl); return 0; }

1つのデータは氏名20バイト、住所40バイト取っています。 従って3番目のデータは60*(3−1)バイト目からですね。 _lseekの所をよく見て下さい。後は説明は不要ですね。 念のために、このプログラムの全体を示しましょう。

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <io.h> #include <string.h> #include <sys\types.h> #include <sys\stat.h> int read_file(void); int write_file(void); int edit_file(void); char file_name[32]; int hdl; int main(void) { char mode[8]; strcpy(file_name, " "); while(1) { printf("1:読み込み 2:追加 3:修正 4:終了 ="); gets(mode); if (mode[0] == '4') break; switch(atoi(mode)) { case 1:read_file(); break; case 2:write_file(); break; case 3:edit_file(); break; default: printf("入力エラーです。\n"); break; } } printf("終了します。\n"); return 0; } int read_file(void) { int cnt = 1; char name[21]; char address[41]; if (strcmp(file_name, " ") == 0) { printf("ファイル名="); gets(file_name); } hdl = _open(file_name, _O_RDONLY); if (hdl == -1) { printf("エラーです\n"); exit(-1); } while(_read(hdl, name, 20) > 0) { _read(hdl, address, 40); printf("[%2d]%s\n", cnt++, name); printf(" %s\n", address); } _close(hdl); return 0; } int write_file(void) { char name[21]; char address[41]; char yn[4]; long fp = 0; if (strcmp(file_name, " ") == 0) { printf("ファイル名="); gets(file_name); } hdl = _open(file_name, _O_WRONLY | _O_CREAT | _O_APPEND, _S_IREAD | _S_IWRITE); while(1) { memset(name, ' ', sizeof(name)); memset(address, ' ', sizeof(address)); printf("氏名="); gets(name); if (strcmp(name, "E") == 0) break; printf("住所="); gets(address); _write(hdl, name, 20); _write(hdl, address, 40); printf("書き込み終了?(y/n)="); gets(yn); if (yn[0] == 'y' || yn[0] == 'Y') break; } _close(hdl); return 0; } int edit_file(void) { char no[8], name[21], address[41], chk[4]; if (strcmp(file_name, " ") == 0) { printf("ファイル名="); gets(file_name); } hdl = _open(file_name, _O_RDWR); if (hdl == -1) { printf("エラーです\n"); exit(-1); } while(1) { printf("\n修正したいデータno="); gets(no); _lseek(hdl, 60L * (atoi(no) - 1) , SEEK_SET); _read(hdl, name, 20); _read(hdl, address, 40); printf("修正するデータは\n"); printf("[%2d]%s\n", atoi(no), name); printf(" %s\n", address); printf("これでよいですか(y/n)="); gets(chk); if (chk[0] == 'y' || chk[0] == 'n') { memset(name, ' ', sizeof(name)); memset(address, ' ', sizeof(address)); printf("氏名="); gets(name); printf("住所="); gets(address); _lseek(hdl, 60L * (atoi(no) - 1), SEEK_SET); _write(hdl, name, 20); _write(hdl, address, 40); } printf("もう1件修正しますか(y/n)="); gets(chk); if (chk[0] == 'n' || chk[0] == 'N') break; } _close(hdl); return 0; }


ちょっと長いですが、前章の説明とあわせてみると たいして難しくはないですね。

scanfを使っていないので、入力の途中に 半角のスペースがあっても大丈夫です。

ファイルを一度読み込んでデータを眺めます。 修正したいデータがあればその番号を指定します。 いきなり、修正してもかまいません。


[Index][総合Index] [Previous Chapter] [Next Chapter]

Update Mar/01/1997 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。