掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

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

掲示板2

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

No.28626

簡易エディタ
投稿者---エディ(2006/10/30 10:57:28)


今、コマンド入力によって文字列編集処理を行うプログラムを作ってます
下のプログラムは作ったプログラムの一部で、入力した桁数(column)に
文字列を挿入する関数です。
ただ下のプログラムですと、一回目に文字列を入力して二回目に文字列を
入力すると1回目に入力した文字列が全て消え、二回目の文字列が表示されてしまいます。
次のようにしたいのですがどうすればよいのでしょうか?

i(insert) : 挿入コマンド
column : 挿入場所(桁数)

一回目の入力
i01
abc

column : 1234567890
buffer : abc


二回目の入力
i01
123

column : 1234567890
buffer : 123abc

どなたかアドバイスお願いします。



char ins(char *p_edt, int column) {
    int len;
    int len1;
    char *ch[EBSIZE];
    
    len = strlen(p_edt);
    if (column > len) { 
        for (p_edt += len; len < column - 1; len++, p_edt++) {
            *p_edt = ' ';
        }
    
    }else {
        if (len + 1 == EBSIZE) {
            len--;
        }
        for (p_edt += len -1; len > column -1; len--, p_edt--) {
            *(p_edt + 1) = *p_edt;
        }
        p_edt++;
    }
    
    fgets(p_edt, EBSIZE, stdin);
    len1 = strlen(p_edt);
    if (*(p_edt + len1 - 1) != '\n') {
        while (getchar() != '\n');
    }
    p_edt[strlen(p_edt)] = '\0';
    return 0;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:簡易エディタ 28627 かずま 2006/10/30 12:54:37
<子記事> Re:簡易エディタ 28648 asd 2006/10/31 17:04:33


No.28627

Re:簡易エディタ
投稿者---かずま(2006/10/30 12:54:37)


> どなたかアドバイスお願いします。

紙と鉛筆を用意して、すべての変数の値の変化を絵に描いてみてください。
それで解決するはずです。


この投稿にコメントする

削除パスワード

No.28628

Re:簡易エディタ
投稿者---エディ(2006/10/30 13:25:38)


早速のお返事ありがとうございます!

> 紙と鉛筆を用意して、すべての変数の値の変化を絵に描いてみてください。
それで解決するはずです。

全てという事はプログラムの最初から最後までってことでしょうか?


下のプログラムは先程のプログラムを少し作り変えてやってみたんですが
今度は自分が目指す挿入が出来たんですが、ただ
入力した文字列全てではなく最初の1文字しか表示されないんですが
これもどこかで数値が食い違ってるんでしょうか?




    fgets(ch, EBSIZE, stdin);/*文字列入力*/
    len = strlen(ch);
    if (*(ch + len - 1) != '\n') {
        while (getchar() != '\n');
    }
    ch[strlen(ch) -1] = '\0';

    switch(cmd){
    case 'i':
        ret = ins(p_edt, column, ch);
        break;
    }
    return ret;
}

char ins(char *p_edt, int column, char *ch)
{
    int len;
    len = strlen(p_edt);
    printf("len = %d\n", len);
    if (column > len) { 
        for (p_edt += len; len < column - 1; len++, p_edt++) {
            *p_edt = ' ';
        }
    
    }else {
        if (len + 1 == EBSIZE) {
            len--;
        }
        for (p_edt += len -1; len > column -1; len--, p_edt--) {
            *(p_edt + 1) = *p_edt;
        }
        p_edt++;
    }

    *p_edt = *ch;/*代入*/
    return 0;
}
    




この投稿にコメントする

削除パスワード

No.28630

Re:簡易エディタ
投稿者---エディ(2006/10/30 14:20:06)


>ins関数の第3引数にchar型へのポインタを指定しているのに、
>実際に使っているのは先頭文字だけ。それでいいのでしょうか?


説明不足ですみません
おっしゃる通りかと。
次のようになってしまいます。


/*文字列入力*/
i01
abcdefg

/*文字列表示*/
column : 1234567890
buffer : a


この投稿にコメントする

削除パスワード

No.28631

Re:簡易エディタ
投稿者---エディ(2006/10/30 15:09:25)


すみません、ややこしい書き方をしてしまい
非常にわかり難いと思いますのでまとめて書きます。

下のプログラムは任意の桁数の場所にコマンド(i)によって
文字列を挿入する だけの プログラムなのですが
ただこのプログラムだと文字列を入力したさいに
どうしても、入力した文字列の先頭の文字しか表示されません。


1回目の入力
i01
abc

column : 1234567890
buffer : abc


2回目の入力
i02
123

column : 1234567890
buffer : a123bc

というようなプログラムにしたいのですが
どうしても間違っている場所がわかりません。

大変お手数ですが教えていただけないでしょうか?



#include <stdio.h>
#include <string.h>

#define DEBUG 0  /* debug mode  0:off  1:on */
#define CBSIZE 8    /* command buffer size */
#define EBSIZE 11   /* edit buffer size */

void disp_inp(char *p_cmd, char *p_edt);
char command(char *p_cmd, char *p_edt);
char ins(char *p_edt, int column, char *ch);

void main()
{
    char cmdbuf[CBSIZE];    /* command buffer */
    char edtbuf[EBSIZE];    /* edit buffer */

    memset(edtbuf, '\0', EBSIZE);   /* edit buffer clear */
    printf("\nThis is Simple 1-line Editor.\n");
    disp_inp(cmdbuf, edtbuf);   /* display edit buffer & input command */

    while (strcmp(cmdbuf, "q\n") != 0) {    /* until q(quit) */
        if (command(cmdbuf, edtbuf) != 0) { /* command process & error? */
            printf("Command Error!\n");
        }
        disp_inp(cmdbuf, edtbuf);   /* display edit buffer & input next command */
    }
}   /* end of main */
void disp_inp(char *p_cmd, char *p_edt)
{
    char cnt;   /* loop counter */
    int no = '1';   /* no. for display */
    int len;    /* string length */

    printf("Column: ");
    for (cnt = 0; cnt < (EBSIZE - 1); cnt++) {
        putchar(no);
        if (no == '9') {
            no = '0';
        }
        else {
            no++;
        }
    }
    printf("\nBuffer: %s\n\n", p_edt);

#if DEBUG
    printf("Column:");
    for (cnt = 0, no = 1; cnt < EBSIZE; cnt++, no++) {
        printf(" %2d", no);
    }
    printFFf("\nHEX:   ");
    for (cnt = 0; cnt < EBSIZE; cnt++, p_edt++) {
        printf(" %02x", p_edt);
    }
    printf("\n\n");
#endif

    printf("Command?   format ->  iaa  daa-bb  raa-bb  (aa,bb:column no.)  q to quit\n");
    fgets(p_cmd, CBSIZE, stdin);    /* input next command */
    len = strlen(p_cmd);
    if (*(p_cmd + len - 1) != '\n') {   /* CR not detected */
        while (getchar() != '\n');  /* skip to CR */
    }
}
char command(char *p_cmd, char *p_edt)
{
    char cmd;   /* command */
    char *ch;
    int column; /* column no. */
    int len;
    int ret;    /* return value */

    /* command */
    cmd = *p_cmd;
    if (cmd != 'i') {
        printf("%c: No such command\n", cmd);
        return 1;
    }
    p_cmd++;
    /* column no. */
    if (*p_cmd >= '0' && *p_cmd <= '9') {   /* numeric */
        column = (*p_cmd & 0x0f) * 10;
    }
    else {
        printf("Column no. not numeric\n");
        return 1;
    }
    p_cmd++;
    if (*p_cmd >= '0' && *p_cmd <= '9') {   /* numeric */
        column += *p_cmd & 0x0f;
    }
    else {
        printf("Column no. not numeric\n");
        return 1;
    }
    if (column == 0 || column > EBSIZE - 1) {   /* column no. incorrect */
        printf("Can't insert. Column no. out of range\n");
        return 1;
    }
    
    fgets(ch, EBSIZE, stdin);
    len = strlen(ch);
    if (*(ch + len - 1) != '\n') {
        while (getchar() != '\n');
    }
    ch[strlen(ch) -1] = '\0';

    ret = ins(p_edt, column, ch);
    return ret;
}
char ins(char *p_edt, int column, char *ch)
{
    int len;
    
    len = strlen(p_edt);
    if (column > len) { 
        for (p_edt += len; len < column - 1; len++, p_edt++) {
            *p_edt = ' ';
        }
    }else {
        if (len + 1 == EBSIZE) {
            len--;
        }
        for (p_edt += len -1; len > column -1; len--, p_edt--) {
            *(p_edt + 1) = *p_edt;
        }
        p_edt++;
    }
    *p_edt = *ch;
    return 0;
}




この投稿にコメントする

削除パスワード

No.28635

Re:簡易エディタ
投稿者---123456789(2006/10/30 20:02:02)


こういうのはフローチャートでたどっていけば、粗方ミスには気づくもんだが。

てか読んでないけど、たった2行の説明しかないプログラムで、なんでこんなにソースがいるんだ?
コメントも全部英語は個人的な意見ですが、不便だと思うんだが。


この投稿にコメントする

削除パスワード

No.28634

Re:簡易エディタ
投稿者---かずま(2006/10/30 19:57:35)


> 全てという事はプログラムの最初から最後までってことでしょうか?

ins() の呼び出しから始めて 3分もすれば間違いに気づくはずですが?

やってみましょう。

入力が

i01
abc

のとき、ins() に入りました。

p_edt: ---> [ \0 \0 \0 .... \0 ]
column: 1
ch: ---> [ a b c \0 ]

strlen(p_edit) を実行しました。
len: 0

column が len より大きいので
  for() の実行を開始します。
  p_edt: 変わらず
  len < column - 1 は成立せず、forループ終了。

else を飛ばして、

*p_edt = *ch; を実行すると、

p_edt: --> [ a \0 \0 .... \0 ]

終わり。

a の後の b と c がコピーされないことがわかりました。

3分もかかりません。

こんなことすらできないでプログラムが作れるのでしょうか?


この投稿にコメントする

削除パスワード

No.28648

Re:簡易エディタ
投稿者---asd(2006/10/31 17:04:33)


別の方かも知れませんが似た様な投稿が他所にありました。

http://hpcgi3.nifty.com/mmgames/patio/patio.cgi?mode=view&no=1035


この投稿にコメントする

削除パスワード

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