|
> read [行数]:指定した行を表示
> write [行数]:指定した行に上書き
> look [行数]:行数から前後5行(計11行)を表示
「行数」というよりも「行番号」ですね。
> しかし、コマンドの認識のやり方がよく分かりません。
> 行数を含むところはどうやって良いのかさっぱりです。
> どのようにすればいいのでしょうか?
サンプルプログラムをつけますので、解読してみてください。
> また、backコマンドを作りたいのですが
> ファイルに直接上書きすると
> backが出来なくなってしまい、これも困っています。
open コマンドでファイルの内容をすべてメモリーに読み込んでおき、
commit なら、ファイルに書き戻す、
back なら、ファイルに書き戻さない、とすればよいでしょう。
以下、バグのあるサンプルプログラムです。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char filename[256];
char *lines[1000];
int nlines;
void open_file(const char *cmd)
{
FILE *fp; char buf[1024];
int n = sscanf(cmd, "%*s%s", buf);
if (n != 1) { puts("usage: open filename"); return; }
if (nlines != 0) { puts("file alread open"); return; }
fp = fopen(buf, "r");
if (!fp) { puts("can't open file"); return; }
strcpy(filename, buf);
for (n = 1; n < 1000 && fgets(buf, sizeof buf, fp); n++)
lines[n] = strdup(buf);
fclose(fp);
nlines = n;
}
void back(void)
{
int i;
for (i = 1; i <= nlines; i++) free(lines[i]);
nlines = 0;
filename[0] = '\0';
exit(0);
}
void commit(void)
{
FILE *fp; int i;
if (!filename[0]) { puts("no file"); return; }
fp = fopen(filename, "w");
if (!fp) { puts("commit failed"); return; }
for (i = 1; i <= nlines; i++)
fputs(lines[i], fp);
fclose(fp);
back();
}
void read_file(const char *cmd)
{
int line;
int n = sscanf(cmd, "%*s%d", &line);
if (n != 1) { puts("usage: read line_number"); return; }
if (line < 1 || line > nlines) { puts("bad line_number"); return; }
fputs(lines[line], stdout);
}
void look_file(const char *cmd)
{
int line, a, b;
int n = sscanf(cmd, "%*s%d", &line);
if (n != 1) { puts("usage: look line_number"); return; }
if (line < 1 || line > nlines) { puts("bad line_number"); return; }
a = line - 5;
if (a < 1) a = 1;
b = line + 5;
if (b > nlines) b = nlines;
for (line = a; line <= b; line++)
fputs(lines[line], stdout);
}
void write_file(const char *cmd)
{
char buf[1024]; int line;
int n = sscanf(cmd, "%*s%d", &line);
if (n != 1) { puts("usage: write line_number"); return; }
if (line < 1 || line > nlines) { puts("bad line_number"); return; }
if (fgets(buf, sizeof buf, stdin)) {
free(lines[line]);
lines[line] = strdup(buf);
}
}
int main(void)
{
char buf[256], cmd[256];
while (printf("$ "), fgets(buf, sizeof buf, stdin)) {
int n = sscanf(buf, "%s", cmd);
if (n != 1) continue;
if (!strcmp(cmd, "open")) open_file(buf);
else if (!strcmp(cmd, "commit")) commit();
else if (!strcmp(cmd, "back")) back();
else if (!strcmp(cmd, "read")) read_file(buf);
else if (!strcmp(cmd, "write")) write_file(buf);
else if (!strcmp(cmd, "look")) look_file(buf);
else puts("?");
}
return 0;
}
|