まずは、main関数にメニューを作りましょう。 そして、必要な作業はこのメニューから関数として 呼び出すようにしましょう。
さて、これだけでは走らないので read_file(), write_file(), edit_file()関数は とりあえず作るだけ作っておいて中身は、 return文だけにしておきましょう。後は、 インクルードするファイルを書いて、とりあえず コンパイルして動かしてみて下さい。 間違ってメニュー選択で2バイト文字などを入力してしまっても 大丈夫です。int mode;としないでchar mode[8];としている点に 注意して下さい。また、scanfを使わずにgetsを使っている点も 注意して下さい。また、switch(mode)ではなく switch(atoi(mode))とした点も大事ですね。 (そんなことわかってる?)それから、これは筆者の 好みなのですが、while(1)で無限ループにして breakで脱出する方法も覚えておいて下さい。 while-do文でも同様のことができます。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; }
次に、住所録ですから当然氏名と住所は必須です。 それぞれの大きさ(バイト数)を決めましょう。 とりあえず氏名は20バイト住所は40バイトまでとします。 文字列には、最後にヌル文字(\0)が入るので実際には name[21]とかaddress[41]などといった感じになります。 それとファイル名はファイルがオープンされていないときは 半角のスペースを入れておきましょう。 そうすればファイル名が半角スペースであれば あらためて、ファイル名の入力を促すようにできます。 それでは、read_file関数を作ってみましょう。
これは、すでにやったことばかりなので説明は不要ですね。 この関数では、データの数が少ないうちはよいのですが 1画面で表示仕切れないときは、最初の方のデータが スクロールしてしまいゆっくりみることができません。 20行以上表示するときは、次の表示を行ってよいか ユーザーに聞くようにプログラムを改良してみて下さい。 そんなに難しくはありません。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; }
それと_openとか_read, _closeなど低水準ファイル入出力
に関係のある関数でマイクロソフトのコンパイラ以外を
お使いの人はそのままではエラーになる可能性があります。
関数の前のアンダスコアはとって下さい。また、
_O_RDONLYの一番最初のアンダスコアもとってください。
次は、write_file関数ですがこれも特に新しいことは出てきません。
_open(file_name, _O_WRONLY | _O_CREAT | _O_APPEND, _S_IREAD | _S_IWRITE);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; }
について少し解説しますが、追加の場合全く新規に ファイルを作る場合もあります。それで_O_CREATが入っています。 すでにファイルが存在する場合は、無視されます。 また、書き込みは追加ですから常にファイルの最後から 行わなくてはいけません。従って_O_APPENDを入れてあります。 そして、マイクロソフト(特有の問題?)のコンパイラでは さらに3番目の引数を付けて下さい。そうしないと作られたファイルの 属性が「読み込み専用」となりまずい問題が生じます。 筆者はこれで引っかかって、このプログラムを作るのに 大変な時間を費やしてしまいました。
すでにお気付きのことと思いますがhdlとfile_nameは グローバル変数にしてあります。
次に、肝心のデータの編集ですが少しばかり説明が必要です。
しかし、紙面?がなくなってきたので次回に説明しましょう。
本日はここまで。
Update Mar/01/1997 By Y.Kumei