【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.22865

コマンドで動く簡易エディタ
投稿者---めえな(2005/08/28 18:09:50)


はじめまして
めえなと申します。

Cは授業でやった程度です。

私はコマンドを入力して
ファイルを操作するプログラムを作りたいと思っています。

たとえば
open:ファイルを開く
commit:ファイルを閉じ編集を確定する
back:ファイルを閉じるが編集を確定しない

read [行数]:指定した行を表示
write [行数]:指定した行に上書き
look [行数]:行数から前後5行(計11行)を表示

以上のようなコマンドがあってそれを打ち込むと
書いた処理をするようなプログラムです。

しかし、コマンドの認識のやり方がよく分かりません。
行数を含むところはどうやって良いのかさっぱりです。
どのようにすればいいのでしょうか?

また、backコマンドを作りたいのですが
ファイルに直接上書きすると
backが出来なくなってしまい、これも困っています。

さらに、writeでは

abcdefg
と書かれている行に
102
と書けというと
102defgとなってしまいます。

どうすればいいのでしょうか・・・?


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:コマンドで動く簡易エディタ 22866 かずま 2005/08/28 19:01:10


No.22866

Re:コマンドで動く簡易エディタ
投稿者---かずま(2005/08/28 19:01:10)


> 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;
}



この投稿にコメントする

削除パスワード

No.22867

Re:コマンドで動く簡易エディタ
投稿者---かずま(2005/08/28 20:03:47)


>    if (nlines != 0) { puts("file alread open"); return; }

訂正します。
     if (filename[0]) { puts("file already open"); return; }



この投稿にコメントする

削除パスワード

No.22868

Re:コマンドで動く簡易エディタ
投稿者---かずま(2005/08/28 20:53:18)


やっぱり、不正な処理で落ちるようなバグはよくないので、
最大のバグだけは修正しておきます。

open_file() の最後は、nlines = n - 1; にしてください。


この投稿にコメントする

削除パスワード

No.22869

Re:コマンドで動く簡易エディタ
投稿者---めえな(2005/08/28 22:47:31)


すばやい回答ありがとうございます。
明日、帰ってきたら解析してみようと思います。


この投稿にコメントする

削除パスワード

No.22898

Re:コマンドで動く簡易エディタ
投稿者---めえな(2005/08/30 13:52:40)


遅くなりましたが
おおよそ理解できました。

これを参考に作ってみたいと思います。
どうもありがとうございました


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧