|
>「エディタ機能(ファイルからの文書の読み込み、文書の入力とファイルへの書き込
> み、行単位の修正)を持った簡単なファイル操作のプログラムを作成せよ」
> 途中までやってみたけれどどうもうまくいきません。
すごい。これだけ、でたらめなプログラムなのに、コンパイルエラーはない。
題名に「(C++)」と書いてあるのに、これは C++ でなく、C のプログラムである。
すみませんが、なぜ、題名に (C++) と書いたのかを説明してもらえますか。
さて、すごく機能の限定された、ほとんど実用にならないおもちゃのエディターなら
簡単に作れますので、参考のため挙げますが、C++ ではなく、C で書いています。
使用できるコマンドは次のとおり。
f [filename] ファイル名の表示と指定。
r 指定されたファイルを読み込む。
w 指定されたファイルに書き出す。
i 注目行の上に、キーボード入力行を挿入する。行入力は . で終了。
d 注目行のひとつ前の行を削除する。
改行 注目行を表示し、次の行を注目行にする。
- 注目行をひとつ前に移動する。
行番号 その行を注目行にし、ひとつ前の行を表示する。
q 終了。
プログラム起動時に、ファイル名を引数にすると、f コマンドと r コマンドが実行されます。
プロンプトは、注目行の行番号: です。最後の行の次に仮想的なエンド行があり、
そこが注目行のときは $: と表示されます。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int cur = 1, end = 1; char *line[1000], buf[1024];
void show(int n) { printf("%6d: %s", n, line[n]); }
int check(int f) { if (!f) puts("?"); return f; }
void add_line(void)
{
if (end < 999) {
int i; for (i = end++; i > cur; --i) line[i] = line[i-1];
line[cur++] = strdup(buf);
}
}
int main(int argc, char **argv)
{
FILE *fp; int i; char *p;
if (argc == 2) { line[0] = strdup(argv[1]); goto read_file; }
for (;;) {
printf(cur == end ? "$:" : "%d: ", cur);
if (fgets(buf, 1024, stdin) == NULL) break;
if (p = strchr(buf, '\n')) *p = '\0';
switch (buf[0]) {
case 'r': read_file:
if (check(line[0] && (fp = fopen(line[0], "r"))))
{ while (fgets(buf, 1024, fp)) add_line(); fclose(fp); }
break;
case 'w':
if (check(line[0] && (fp = fopen(line[0], "w"))))
{ for (i = 1; i < end; i++) fputs(line[i], fp); fclose(fp); }
break;
case 'f':
if (buf[1]==' ') {free(line[0]); line[0] = strdup(buf+2); }
else if (check(buf[1]=='\0')) printf("filename=%s\n", line[0]);
break;
case 'i':
while (fgets(buf, 1024, stdin) && (buf[0]!='.' || buf[1]!='\n'))
add_line();
break;
case 'd':
if (check(cur > 1)) {
free(line[cur-1]);
for (i = cur; i <= end; ++i) line[i-1] = line[i];
if (cur == end--) cur = end;
if (cur > 1) show(cur-1);
}
break;
case '\0': if (check(cur < end)) show(cur++); break;
case '-': if (check(cur > 1) && --cur > 1) show(cur-1); break;
case 'q': exit(0);
default:
if (check(isdigit((unsigned char)buf[0]))) {
if ((i = atoi(buf)) < 1) i = 1;
if (i > end) i = end;
if ((cur = i) > 1) show(cur-1);
}
}
}
return 0;
}
|