マイクロソフト以外のコンパイラでは最初のアンダスコアを取って下さい。 これは、ファイルポインタの移動のための関数です。単に、ファイルのどこ から、読み書きするかを示すものと考えて下さい。 ファイルの途中を変更するときに必要ですね。handleは _openしたとき取得できますね。originはファイルのどこを起点に するかです。#include <io.h> 関数宣言のためにのみ必要 #include <stdio.h> long _lseek(int handle, long offset, int origin);
の中から選びます。 offsetはoriginから何バイト先をファイルポインタにするかを 指定します。SEEK_SET ファイルの先頭 SEEK_CUR ファイルポインタのカレント位置 SEEK_END ファイルの終端
とすれば、ファイルの最初から100バイト先をファイルポインタとする という意味になります。 それでは、さっそくedit_file関数を作ってみましょう。_lseek(hdl, 100L, SEEK_SET);
1つのデータは氏名20バイト、住所40バイト取っています。 従って3番目のデータは60*(3−1)バイト目からですね。 _lseekの所をよく見て下さい。後は説明は不要ですね。 念のために、このプログラムの全体を示しましょう。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; }
#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を使っていないので、入力の途中に
半角のスペースがあっても大丈夫です。
ファイルを一度読み込んでデータを眺めます。
修正したいデータがあればその番号を指定します。
いきなり、修正してもかまいません。
Update Mar/01/1997 By Y.Kumei