掲示板利用宣言

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

 私は

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

掲示板2

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

No.23394

双方向リストを用いたstrinput関数について
投稿者---bob(2005/09/29 13:37:00)


双方向リストを用いて文字入力なんですが、構造体に入力までは出来ていると思うのですがその構造体をどうしてもstatic char bufferに代入することが出来ません。
誰か知恵を貸してください。
あと字下げ間違っていたらすいません。

#include <conio.h>
#include <stdio.h>
#include <ctype.h>

#define BUF_LEN (80)

struct InputData {
char Data;
struct InputData *BackPtr;
struct InputData *NextPtr;
}InputData={0,0,0};         //初期化

struct InputBuffer {
struct InputData *StartPtr;
struct InputData *EndPtr;
struct InputData Buffer[BUF_LEN];
}*StartPtr={0},*EndPtr={0};      //初期化

char *StrInput(char *DefaultStr, int InputLen);

int main()
{
char *buf;
buf = StrInput("",BUF_LEN);
printf("\n");
printf("%s", buf);
return 0;
}

char *StrInput(char *DefaultStr, int InputLen)
{
static char buffer[BUF_LEN+1];
struct InputBuffer input;
int a=0;
int b=0;

for(a=0; a<=BUF_LEN; a++){ //このfor文にて入力された1文字を空
InputData.Data=getch();   //き領域('0x00')に代入
if(input.Buffer[a].Data==0x00){
input.Buffer[a].Data=InputData.Data;
struct InputData *NextPtr;
}
if(InputData.Data==0x0d){ enterキー入力で入力終了
break;
}
}
 for(b=0 ,a=0; b<=BUF_LEN+1 ,a<=BUF_LEN+1; b++ ,a++){ //ここで
  buffer[b]=input.Buffer[a].Data;   //構造体を配列に代入      
   if(input.Buffer[a].Data==0x00){ //構造体に文字がなくなりNULL
    buffer[b]='\0';       //のみになったら終端文字を代入
    break;
   }
   if(b=BUF_LEN+1){ //bが81になったら81に終端文字を代入
    buffer[BUF_LEN+1]='\0';
    break;
   }

putchar(buffer[b]);
return &buffer[0];
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:双方向リストを用いたstrinput関数について 23395 shu 2005/09/29 14:14:38
<子記事> Re:双方向リストを用いたstrinput関数について 23396 まきじ 2005/09/29 14:14:44
<子記事> Re:双方向リストを用いたstrinput関数について 23398 まきじ 2005/09/29 14:43:30
<子記事> 双方向リストを用いたstrinput関数についてのポインタの設定方法 23432 bob 2005/09/30 17:21:50
<子記事> リスト構造でのカーソル移動、消去、挿入、上書きについて 23562 bob 2005/10/11 10:43:07
<子記事> カーソル移動について 23573 bob 2005/10/12 11:35:36
<子記事> 構造体の初期化について 23574 bob 2005/10/12 15:11:40


No.23395

Re:双方向リストを用いたstrinput関数について
投稿者---shu(2005/09/29 14:14:38)


>双方向リストを用いて文字入力なんですが、構造体に入力までは出来ていると思うのですがその構造体をどうしてもstatic char bufferに代入することが出来ません。
>誰か知恵を貸してください。
>あと字下げ間違っていたらすいません。

双方向リストが難しいなら、単方向リスト、
単方向リストが難しいなら、(二次元配列)配列にして、
順番にデータが入力・代入される「プログラムの流れ」をつかむ。

プログラムの流れ自体は、単方向リストになっても、
双方向リストになっても、さほど変わりはしません。
(変数にアクセスするための、構文が少し変化するだけ)

わからなかったら、表示してみる。

表示できたということは、正しくアクセスできたということです。
正しくアクセスできたということは、他の変数に代入したり、
自らが変数なら、同じ型の他の値を代入したりできます。

表示できなかったということは……


この投稿にコメントする

削除パスワード

No.23400

Re:双方向リストを用いたstrinput関数について
投稿者---bob(2005/09/29 15:31:44)


>>双方向リストを用いて文字入力なんですが、構造体に入力までは出来ていると思うのですがその構造体をどうしてもstatic char bufferに代入することが出来ません。
>>誰か知恵を貸してください。
>>あと字下げ間違っていたらすいません。
>
>双方向リストが難しいなら、単方向リスト、
>単方向リストが難しいなら、(二次元配列)配列にして、
>順番にデータが入力・代入される「プログラムの流れ」をつかむ。
>
>プログラムの流れ自体は、単方向リストになっても、
>双方向リストになっても、さほど変わりはしません。
>(変数にアクセスするための、構文が少し変化するだけ)
>
>わからなかったら、表示してみる。
>
>表示できたということは、正しくアクセスできたということです。
>正しくアクセスできたということは、他の変数に代入したり、
>自らが変数なら、同じ型の他の値を代入したりできます。
>
>表示できなかったということは……
知恵ありがとうございます。
今、やってみたのですがどうしても1文字しか出力しません。
あと、テンプラリーを用いるとやりやすいと先日教えてもらったのですが
テンプラリーという関数自体よく分からないので教えていただけませんでしょうか?
よろしくお願いいたします。


この投稿にコメントする

削除パスワード

No.23396

Re:双方向リストを用いたstrinput関数について
投稿者---まきじ(2005/09/29 14:14:44)


>誰か知恵を貸してください。

23312 や 23317 の続きだと思いますが、
なぜ新らたにスレッドを立てるのでしょうか?

ソースは、インデントしてHTML形式にして提示して下さい。


この投稿にコメントする

削除パスワード

No.23398

Re:双方向リストを用いたstrinput関数について
投稿者---まきじ(2005/09/29 14:43:30)


23312 でご自分で
>もうあまりにも複雑すぎて分からなくなってしまいました。。。
と仰ってますが、作った本人でさえ訳の判らないものを
私(達)に詠めと?
と云うことで、双方向リストのサンプルです。

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

#define N 256

typedef struct DATA{
    char data[N];
    struct DATA *prev;
    struct DATA *next;
}NODE;

void print_node(NODE* head){

    NODE *p;
    
    for(p = head; p; p = p -> next){
        printf("%s\n",p -> data);
    }
    
}

int main(void){

    NODE *head = NULL;
    NODE *old = NULL;
    NODE *p;
    char buf[N];
    
    while(printf("data:"),fgets(buf,N,stdin)){
        if(buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0';
        p = malloc(sizeof(NODE));
        strcpy(p->data,buf);
        p -> next = NULL;
        p -> prev = old;
        if(!head) head = p;
        else old -> next = p;
        old = p;
    }
    
    print_node(head);
    
    return 0;
}




この投稿にコメントする

削除パスワード

No.23399

Re:双方向リストを用いたstrinput関数について
投稿者---bob(2005/09/29 15:26:28)


><pre>23312 でご自分で
>もうあまりにも複雑すぎて分からなくなってしまいました。。。
と仰ってますが、作った本人でさえ訳の判らないものを
私(達)に詠めと?
と云うことで、双方向リストのサンプルです。

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

#define N 256

typedef struct DATA{
char data[N];
struct DATA *prev;
struct DATA *next;
}NODE;

void print_node(NODE* head){

NODE *p;

for(p = head; p; p = p -> next){
printf("%s\n",p -> data);
}

}

int main(void){

NODE *head = NULL;
NODE *old = NULL;
NODE *p;
char buf[N];

while(printf("data:"),fgets(buf,N,stdin)){
if(buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0';
p = malloc(sizeof(NODE));
strcpy(p->data,buf);
p -> next = NULL;
p -> prev = old;
if(!head) head = p;
else old -> next = p;
old = p;
}

print_node(head);

return 0;
}

void print_node(NODE* head)

for(p = head; p; p = p -> next){
printf("%s\n",p -> data)

while(printf("data:"),fgets(buf,N,stdin)){
if(buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0';

サンプルまで作っていただいてありがとうございます。
ですが上記のソースの意味がよく分からないので教えていただけませんか?
よろしくお願いいたします。



</pre>



この投稿にコメントする

削除パスワード

No.23401

Re:双方向リストを用いたstrinput関数について
投稿者---まきじ(2005/09/29 15:50:29)


引用は最小限にして下さい。

>上記のソースの意味がよく分からないので教えていただけませんか?

どこが判らないのですか?(「全部」は無しね(^^;)

ソース全体としては、入力された文字列を要素とする
双方向リストを作成してます。

繋ぐ部分だけ解説しときます。

>p -> next = NULL;

追加されたノード(p)は末尾のノードなので、
追加されたノードの前方のノード(next) は NULL にする。

>p -> prev = old;

old は前回追加されたノードなので、追加されたノードの
後方のノード(prev) は old にする。

>if(!head) head = p;

先頭のノード(head) が NULL ということは、
一回目の追加なので、先頭のノードは追加されたノードにする。

>else old -> next = p;

先頭のノードが NULL でないということは、二回目以降なので、
前回追加されたノードの前方のノードを追加されたノードにする。

>old = p;

追加されたノードを old に記憶しておく。


この投稿にコメントする

削除パスワード

No.23409

Re:双方向リストを用いたstrinput関数について
投稿者---bob(2005/09/29 18:23:43)


分かりやすい説明ありがとうございます。
サンプルと本でなんとかがんばってやってみます。
また分からなくなったときはご迷惑かもしれませんが、よろしくお願いします。
あとできれば字下げの方法を教えていただけませんか?


この投稿にコメントする

削除パスワード

No.23432

双方向リストを用いたstrinput関数についてのポインタの設定方法
投稿者---bob(2005/09/30 17:21:50)


#include <conio.h>
#include <stdio.h>
#include <ctype.h>

#define BUF_LEN (80)

    struct InputData {
        char Data;
        struct InputData *BackPtr;
        struct InputData *NextPtr;
    }InputData={0,0,0};     
    
    struct InputBuffer {
        struct InputData *StartPtr;
        struct InputData *EndPtr;
        struct InputData Buffer[BUF_LEN];
    }*StartPtr={0},*EndPtr={0};   
    
char *StrInput(char *DefaultStr, int InputLen); 
int main()
{
    char *buf;
    buf = StrInput("",BUF_LEN);
    printf("\n");
    printf("%s", buf);
    return 0;   
}
    
char *StrInput(char *DefaultStr, int InputLen)
{   
    static char buffer[BUF_LEN+1];
    struct InputBuffer input;
    int a=0;
    int b=0;
    
 ※   InputData.NextPtr=&input.Buffer[a+1];
    InputData.BackPtr=&input.Buffer[a-1];   
    input.StartPtr=&input.Buffer[0];
    input.EndPtr=&input.Buffer[a];

        for(a=0;;a++){          InputData.Data=getch();
            input.Buffe[a].Data=InputData.Data;
            if(a==BUF_LEN){
                break;
            }
            if(InputData.Data==0x0d){
                input.Buffer[a].Data=0x00;    
                break;
            }   
        }
        
        
        tmpPtr=input.StartPtr;    
        for(b=0 ,a=0; b<=BUF_LEN+1 ,a<=BUF_LEN+1; b++ ,a++){
            printf("\nこれ%d\nそれ%d\n",a,b);
            buffer[b]=input.Buffer[a].Data;
            printf("あれ%d\n",input.Buffer[a].Data);
            if(input.Buffer[a].Data==0x00){
                buffer[b]='\0';
                break;
            }
            if(b==BUF_LEN+1){
                buffer[BUF_LEN+1]='\0';
                break;
            }      
        }
    putchar(buffer[b]);  
    return &buffer[0];  
}



昨日あれから、がんばってなんとか以下のようなソースを書くことができました。
しかしこれは双方向でもなければ単方向でもないものであることに気がついたのですが、このソースでどうやってポインタを設定したらよいのかわかりません。



この投稿にコメントする

削除パスワード

No.23433

Re:双方向リストを用いたstrinput関数についてのポインタの設定方法
投稿者---まきじ(2005/10/01 00:15:26)


>このソースでどうやってポインタを設定したらよいのかわかりません。

リスト構造 について勉強し直しましょう。

>しかしこれは双方向でもなければ単方向でもないものであることに気がついたのですが、

双方向でも単方向でもない事に気付いたのなら、
少しぐらい、どこを直せば良いか判るのでは?

# 私は、そのソースを詠む気にはなれない。
# 双方向も単方向も、構造体は一つで Backptr と Nextptr の
# 操作(繋ぎ変え)だけで実現できます。


この投稿にコメントする

削除パスワード

No.23480

ポインタのforもしくはwhileを使って配列にいれる方法について
投稿者---bob(2005/10/04 13:52:44)


for(input.Buffer[i]=input.Buffer[0];input.Buffer!=0x00;tmp.NextPtr){
buffer[b]=input.Buffer[i].Data;
putchar(buffer[b]);
b++;
}
ポインタの設定は出来たのですが、それをbuffer内に入れることが出来ません。
上記のやり方は開始時をstartptrにあたるinput.Buffer[0]にして条件をNULL以外とし、tmp.NextPtrで次のポインタに移ることにしているのですが、出来ません。
誰か助けてください。よろしくお願いします。



この投稿にコメントする

削除パスワード

No.23481

Re:ポインタのforもしくはwhileを使って配列にいれる方法について
投稿者---まきじ(2005/10/04 14:24:35)


>for(input.Buffer[i]=input.Buffer[0];input.Buffer!=0x00;tmp.NextPtr)

input.Buffer != 0x00 の条件は常に真になり無限ループなります。
input.Buffer は &input.Buffer[0] と同じですよ。

>tmp.NextPtrで次のポインタに移ることにしているのですが、出来ません。

input.Buffer は配列なので、NextPtr を使わなくても
添え字を増やせば次の要素にアクセスできます。


この投稿にコメントする

削除パスワード

No.23494

あれから・・・
投稿者---bob(2005/10/04 17:38:56)


for(input.Buffer[i].Data=input.Buffer[0].Data; i<=BUF_LEN; i++){
buffer[b]=input.Buffer[i].Data;
if(input.Buffer[i].Data==0x00){
buffer[b]='\0';
break;
}
putchar(buffer[b]);
b++;
if(b==BUF_LEN+1){
buffer[b]='\0';
break;
}
}
return &buffer[0];
}
先ほどはありがとうございました。
あれからなんとかできましたが、returnでbufferの先頭ポインタを返したのに出力は先頭の入力文字しか返ってきません。
しかしbuffer内には入力文字は入っていることは確認済みなんですがどうしても原因がわかりません。
どうか教えてください。
よろしくお願いいたします。



この投稿にコメントする

削除パスワード

No.23495

Re:あれから・・・
投稿者---RiSK(2005/10/04 22:43:58)


※題名は具体的に!
※ソースの添付は「HTML変換ツール」で字下げ!

>あれからなんとかできましたが、

「なんとかした」が回答者には分かりません。

>returnでbufferの先頭ポインタを返したのに
>出力は先頭の入力文字しか返ってきません。
>しかしbuffer内には入力文字は入っていることは確認済み

この三点が正しいことはなぜ分かりましたか?

結局,ソース全部貼るのが,楽かな。


この投稿にコメントする

削除パスワード

No.23498

先頭ポインタを返しているはずなんですがbufferに1文字しか返って来ません。
投稿者---bob(2005/10/05 09:13:26)


長々とソースが続きますがお許しください。
#include <conio.h>
#include <stdio.h>
#include <ctype.h>

#define BUF_LEN (80)

    struct InputData {
        char Data;
        struct InputData *BackPtr;
        struct InputData *NextPtr;
    };
    
    struct InputBuffer {
        struct InputData *StartPtr;
        struct InputData *EndPtr;
        struct InputData Buffer[BUF_LEN];
    };
    
char *StrInput(char *DefaultStr, int InputLen); 
int main()
{
    char DefaultStr[BUF_LEN]="";
    char *buf;
    int InputLen=0;
    buf = StrInput("",BUF_LEN);
    printf("\n");
    printf("あれ%d", buf);
    return 0;   
}
    
char *StrInput(char *DefaultStr, int InputLen)
{   
    int a=0;
    int b=0;
    int c=0;
    int i=0;
    static char buffer[BUF_LEN+1];
    struct InputBuffer input;
    
    input.StartPtr=NULL;
    input.EndPtr=NULL;
    struct InputData tmp={0x00, NULL, NULL};
    for(c=0; c<=BUF_LEN; c++){
        input.Buffer[c].Data=0x00;
    }
    
        for(i=0; i<=BUF_LEN; i++){
            tmp.Data=getch();
            if(input.Buffer[i].Data==0x00){
                input.Buffer[i].Data=tmp.Data;
            }   
            if(input.StartPtr!=NULL){
                tmp.BackPtr=input.EndPtr;
                tmp.NextPtr=input.Buffer;
                input.EndPtr=&input.Buffer[i];      
            }
            if(input.StartPtr==NULL){
                input.StartPtr=&input.Buffer[0];
                input.EndPtr=input.StartPtr;
            }         
            if(tmp.Data==0x0d){
                input.Buffer[i].Data=0x00;
                tmp.BackPtr=input.EndPtr;
                tmp.NextPtr=input.Buffer;
                input.EndPtr=tmp.BackPtr;         
                break;      
            }
        }
    i=0;                
    for(input.Buffer[i].Data=input.Buffer[0].Data; i<=BUF_LEN; i++){
        buffer[b]=input.Buffer[i].Data;
        if(input.Buffer[i].Data==0x00){
            buffer[b]='\0';
            break;
        }   
        putchar(buffer[b]);
        b++;
        if(b==BUF_LEN+1){
            buffer[b]='\0';
            break;
        }
    }
    return &buffer[0];      
}   



よろしくお願いいたします。



この投稿にコメントする

削除パスワード

No.23501

解決したのですが、今度はアプリケーションエラーが出てくるのですが、どこがいけないのでしょうか?
投稿者---bob(2005/10/05 13:07:42)


>長々とソースが続きますがお許しください。
><pre>#include <conio.h>
#include <stdio.h>
#include <ctype.h>

#define BUF_LEN (80)

struct InputData {
char Data;
struct InputData *BackPtr;
struct InputData *NextPtr;
};

struct InputBuffer {
struct InputData *StartPtr;
struct InputData *EndPtr;
struct InputData Buffer[BUF_LEN];
};

char *StrInput(char *DefaultStr, int InputLen);
int main()
{
char DefaultStr[BUF_LEN]="";
char *buf;
int InputLen=0;
buf = StrInput("",BUF_LEN);
printf("\n");
printf("あれ%d", buf);
return 0;
}

char *StrInput(char *DefaultStr, int InputLen)
{
int a=0;
int b=0;
int c=0;
int i=0;
static char buffer[BUF_LEN+1];
struct InputBuffer input;

input.StartPtr=NULL;
input.EndPtr=NULL;
struct InputData tmp={0x00, NULL, NULL};
for(c=0; c<=BUF_LEN; c++){
input.Buffer[c].Data=0x00;
}

for(i=0; i<=BUF_LEN; i++){
tmp.Data=getch();
if(input.Buffer[i].Data==0x00){
input.Buffer[i].Data=tmp.Data;
}
if(input.StartPtr!=NULL){
tmp.BackPtr=input.EndPtr;
tmp.NextPtr=input.Buffer;
input.EndPtr=&input.Buffer[i];
}
if(input.StartPtr==NULL){
input.StartPtr=&input.Buffer[0];
input.EndPtr=input.StartPtr;
}
if(tmp.Data==0x0d){
input.Buffer[i].Data=0x00;
tmp.BackPtr=input.EndPtr;
tmp.NextPtr=input.Buffer;
input.EndPtr=tmp.BackPtr;
break;
}
}
i=0;
for(input.Buffer[i].Data=input.Buffer[0].Data; i<=BUF_LEN; i++){
buffer[b]=input.Buffer[i].Data;
if(input.Buffer[i].Data==0x00){
buffer[b]='\0';
break;
}
putchar(buffer[b]);
b++;
if(b==BUF_LEN+1){
buffer[b]='\0';
break;
}
}
return &buffer[0];
}


</pre>
>よろしくお願いいたします。




この投稿にコメントする

削除パスワード

No.23519

構造体のカーソルの移動について
投稿者---bob(2005/10/06 13:46:44)


構造体の双方向リストはできたのですが、
次のカーソル移動、文字の消去、挿入、上書きのイメージがよくわかりません。
文字の消去は消去するポインタの前と次のポインタを設定。
挿入も前のポインタの次のポインタを設定し次のポインタには前のポインタを設定し挿入文字の前と次のポインタを設定すればよいのはわかったのですが、カーソルの移動、上書きのやり方がイメージできません。
どうすればよいのか知恵を貸してください。
また消去、挿入も考え方が違っていれば知恵を貸してください。
よろしくお願いします。


この投稿にコメントする

削除パスワード

No.23522

Re:構造体のカーソルの移動について
投稿者---まきじ(2005/10/06 14:38:08)


>構造体の双方向リストはできたのですが、
>次のカーソル移動、文字の消去、挿入、上書きのイメージがよくわかりません。

マルチポストは駄目ですよ。
ここでも云われていますが双方向リストになってないです。
なってるにしても無駄が多すぎ。

struct InputData Buffer[BUF_LEN]; はなぜ配列?
リスト構造と云えば malloc() などで動的に領域を確保するのが一般的かと。


この投稿にコメントする

削除パスワード

No.23523

Re:構造体のカーソルの移動について
投稿者---まきじ(2005/10/06 14:42:25)


一応を云っときますが、投稿を削除したりしない様に。
マルチポスト先で続けて貰っても構いませんので
こちらスレでそれなりの報告をしてからどうぞ。


この投稿にコメントする

削除パスワード

No.23528

親切にありがとうございます。
投稿者---bob(2005/10/06 16:33:23)


なんかすいません。
でもマルチポストのほうは今見て、参照が多いわりに返信がないのと関係があるんですか?
あとmalloc関数のことなんですが、今回の課題ではstruct InputData配列の領域を利用することが決められているんです。
あと無駄が多い以外に上記のことをふまえても双方向リストになっていないんでしょうか?


この投稿にコメントする

削除パスワード

No.23531

Re:親切にありがとうございます。
投稿者---まきじ(2005/10/06 17:05:45)


>参照が多いわりに返信がないのと関係があるんですか?

見てないだけか、ソースが複雑すぎてレスが付けられないかの
どちらかでしょう。

>あとmalloc関数のことなんですが、今回の課題ではstruct InputData配列の領域を利用することが決められているんです。

なら、InputBuffer の StartPtr と EndPtr は不要の様な気がします。
Buffer[0] と Buffer[1] と Buffer[N - 1]の例を示すと

Buffer[0].Data = '0';
Buffer[0].BackPtr = NULL;
Buffer[0].NextPtr = &Buffer[1];

Buffer[1].Data = '1';
Buffer[1].BackPtr = &Buffer[0];
Buffer[1].NextPtr = &Buffer[2];

Buffer[N - 1].Data = 'N';
Buffer[N - 1].BackPtr = &Buffer[N - 2];
Buffer[N - 1].NextPtr = NULL;

の様な感じでは?

>あと無駄が多い以外に上記のことをふまえても双方向リストになっていないんでしょうか?

Buffer が配列の時点でリスト構造とは云えない。
上記の示した例で要素を増やすと最大でも BUF_LEN 個の
要素しか追加できない。
それに対して、一般的にリスト構造と云われてるものは、
原則いくらでも追加できます。

# 会社の課題でも学校の課題でもどちらでも構いませんが
# 判らないのなら出題者に質問しては如何でしょうか?
# 少なくとも、ここでそのソースを提示しても
# 貴方が期待する解答は得られないと思いますよ。


この投稿にコメントする

削除パスワード

No.23532

Re:親切にありがとうございます。
投稿者---REE(2005/10/06 18:06:11)


>なんかすいません。
>でもマルチポストのほうは今見て、参照が多いわりに返信がないのと関係があるんですか?
>あとmalloc関数のことなんですが、今回の課題ではstruct InputData配列の領域を利用することが決められているんです。

配列を利用してのリストであれば、こうなりませんか?
struct InputData {
char Data;
int BackPtr;
int NextPtr;
};

struct InputBuffer {
int StartPtr;
int EndPtr;
struct InputData Buffer[BUF_LEN];
};

intになっているものは、InputBuffer::Buffer配列のindexを表します。



この投稿にコメントする

削除パスワード

No.23562

リスト構造でのカーソル移動、消去、挿入、上書きについて
投稿者---bob(2005/10/11 10:43:07)


あれからなんとか、入力までは出来たのでですが、どうしてもカーソル移動、文字の消去、挿入、上書きのイメージが出来ません。
だれか以下のソースでどの構造体、char、ポインタをやっていけばいいのか教えてください。
よろしくお願いします。
ちなみにカーソル移動、消去、挿入はヒントにこう書いてあります。

・カーソル移動
_=カーソル
ABC_     この場合0〜3まで移動可能
Char X[4]
ABCD     この場合D(0〜4)まで移動可能

消去
ABCD       Bを消去
ACD        カーソルはC

挿入
ABCD       挿入キー(Insert)を押すと
A BCD      となりカーソルはBにある。


#include <conio.h>
#include <stdio.h>
#include <ctype.h>

#define BUF_LEN (80)

 struct InputData {
 char Data;
 struct InputData *BackPtr;
 struct InputData *NextPtr;
 };

 struct InputBuffer {
 struct InputData *StartPtr;
 struct InputData *EndPtr;
 struct InputData Buffer[BUF_LEN];
 };

char *StrInput(char *DefaultStr, int InputLen);
int main()
{
 char DefaultStr[BUF_LEN]="";
 char *buf;
 int InputLen=0;
 buf = StrInput("",BUF_LEN);
 printf("\n");
 printf("%d", buf);
 return 0;
}

char *StrInput(char *DefaultStr, int InputLen)
{
 int a=0;
 int b=0;
 int c=0;
 int i=0;
 static char buffer[BUF_LEN+1];
 struct InputBuffer input;

 input.StartPtr=NULL;
 input.EndPtr=NULL;
 struct InputData tmp={0x00, NULL, NULL};
 for(c=0; c<=BUF_LEN; c++){
 input.Buffer[c].Data=0x00;
}

 for(i=0; i<=BUF_LEN; i++){
  tmp.Data=getch();
  if(input.Buffer[i].Data==0x00){
   input.Buffer[i].Data=tmp.Data;
  }
  if(input.StartPtr!=NULL){
   tmp.BackPtr=input.EndPtr;
   tmp.NextPtr=input.Buffer;
   input.EndPtr=&input.Buffer[i];
  }
  if(input.StartPtr==NULL){
   input.StartPtr=&input.Buffer[0];
   input.EndPtr=input.StartPtr;
 }
  if(tmp.Data==0x0d){
   input.Buffer[i].Data=0x00;
   tmp.BackPtr=input.EndPtr;
   tmp.NextPtr=input.Buffer;
   input.EndPtr=tmp.BackPtr;
   break;
  }
 }
 i=0;
 for(input.Buffer[i].Data=input.Buffer[0].Data; i<=BUF_LEN; i++){
  buffer[b]=input.Buffer[i].Data;
  if(input.Buffer[i].Data==0x00){
   buffer[b]='\0';
   break;
 }
 putchar(buffer[b]);
 b++;
  if(b==BUF_LEN+1){
   buffer[b]='\0';
   break;
  }
 }
return &buffer[0];
}



この投稿にコメントする

削除パスワード

No.23563

Re:リスト構造でのカーソル移動、消去、挿入、上書きについて
投稿者---まきじ(2005/10/11 11:14:08)


>あれからなんとか、入力までは出来たのでですが、

コンパイルエラーだらけですが?
(VCTK2003 で warning level 4 でコンパイル)

a.c
a.c(22) : warning C4189: 'DefaultStr' : local variable is initialized but not referenced
a.c(24) : warning C4189: 'InputLen' : local variable is initialized but not referenced
a.c(42) : error C2143: syntax error : missing ';' before 'type'
a.c(48) : error C2065: 'tmp' : undeclared identifier
a.c(48) : error C2224: left of '.Data' must have struct/union type
a.c(50) : error C2224: left of '.Data' must have struct/union type
a.c(53) : error C2224: left of '.BackPtr' must have struct/union type
a.c(54) : error C2224: left of '.NextPtr' must have struct/union type
a.c(61) : error C2224: left of '.Data' must have struct/union type
a.c(63) : error C2224: left of '.BackPtr' must have struct/union type
a.c(64) : error C2224: left of '.NextPtr' must have struct/union type
a.c(65) : error C2224: left of '.BackPtr' must have struct/union type


この投稿にコメントする

削除パスワード

No.23564

Re:リスト構造でのカーソル移動、消去、挿入、上書きについて
投稿者---bob(2005/10/11 13:28:11)


すみません。まだ出来てないソースを添付してしまいました。
こちらが出来たソースです。

#include <conio.h>
#include <stdio.h>
#include <ctype.h>

#define BUF_LEN (80)

 struct InputData {
  char Data;
  struct InputData *BackPtr;
  struct InputData *NextPtr;
 };

 struct InputBuffer {
  struct InputData *StartPtr;
  struct InputData *EndPtr;
  struct InputData Buffer[BUF_LEN+1];
 };

char *StrInput(char *DefaultStr, int InputLen);
int main()
{
 char DefaultStr[BUF_LEN+1]="";
 char *buffer;
 int InputLen=0;
 buffer = StrInput("",BUF_LEN+1);
 printf("\n");
 printf("%s", buffer);
 return 0;
}

char *StrInput(char *DefaultStr, int InputLen)
{
 int a=0;
 int b=0;
 int c=0;
 int i=0;
 static char buffer[BUF_LEN+1];
 struct InputBuffer input;

 input.StartPtr=NULL;
 input.EndPtr=NULL;
 struct InputData tmp={0x00, NULL, NULL};
  for(c=0; c<=BUF_LEN; c++){
   input.Buffer[c].Data=0x00;
  }

 for(i=0; i<=BUF_LEN+1; i++){
  tmp.Data=getch();
  if(input.Buffer[i].Data==0x00){
   input.Buffer[i].Data=tmp.Data;
  }
  if(input.StartPtr==NULL){
   input.StartPtr=&input.Buffer[0];
   input.EndPtr=input.StartPtr;
  }
  if(input.StartPtr!=NULL){
   tmp.BackPtr=input.EndPtr;
   tmp.NextPtr=input.Buffer;
   input.EndPtr=&input.Buffer[i];
  }
  if(tmp.Data==0xe0,0x4b){
   struct InputData *tmp2;
   tmp2=input.Buffer;
   tmp2=input.StartPtr;
   tmp2=tmp2->BackPtr;
  }
  if(tmp.Data==0xe0,0x4d){
   struct InputData *tmp2;
   tmp2=input.StartPtr;
   tmp2=tmp2->NextPtr;
  }
  if(tmp.Data==0x0d){
   input.Buffer[i].Data=0x00;
   tmp.BackPtr=input.EndPtr;
   tmp.NextPtr=NULL;
   input.EndPtr=tmp.BackPtr;
   break;
  }
  if(i==BUF_LEN){
   tmp.BackPtr=input.EndPtr;
   tmp.NextPtr=NULL;
   input.EndPtr=&input.Buffer[BUF_LEN];
   break;
  }
 putchar(input.Buffer[i].Data);
}
 printf("\n");
 i=0;
 for(input.Buffer[i].Data=input.Buffer[0].Data; i<=BUF_LEN+1; i++){
  buffer[b]=input.Buffer[i].Data;
  putchar(buffer[b]);
   if(input.Buffer[i].Data==0x00){
    buffer[b]='\0';
    break;
   }
  b++;
   if(i==BUF_LEN+1){
    buffer[b]='\0';
    break;
   }
 }
 return &buffer[0];
}




この投稿にコメントする

削除パスワード

No.23565

Re:リスト構造でのカーソル移動、消去、挿入、上書きについて
投稿者---まきじ(2005/10/11 16:26:43)


N 番目を削除する場合
Buffer[N - 1] の NextPtr を Buffer[N] の NextPtr
Buffer[N + 1] の BackPtr を Buffer[N] の BackPtr
にする。

N 番目の挿入する場合
Buffer[N] を Buffer[N + 1]に代入しずらす。
(Buffer の末尾から、全体をずらす必要がある)
代入後の Buffer[N + 1] の BackPtr を &Buffer[N]
Buffer[N + 1] の NextPtr を &Buffer[N + 1]
にする。

N 番目に上書きする場合 Buffer[N].Data に値を代入。

移動
StartPtr = &Buffer[0];
EndPtr = &Buffer[N];

for(p = StartPtr ; p != NULL ; p = p.NextPtr){
}

# input. は省略してます。


この投稿にコメントする

削除パスワード

No.23572

Re:リスト構造でのカーソル移動、消去、挿入、上書きについて
投稿者---bob(2005/10/12 11:23:47)


ありがとうございます。
消去、挿入、上書きの考え方が分かりました。



この投稿にコメントする

削除パスワード

No.23573

カーソル移動について
投稿者---bob(2005/10/12 11:35:36)


カーソル移動についてなんですが、
ソースを作ってコンパイルは通ったのですが、
カーソルが移動しません。
exeで実行すると
 12_ の状態からだと一回←を入力すると、12_で二回目で
 12●_(●には知らない漢字が入る。)となります。
どうしてか教えてください。
よろしくお願いします。

・流れ
 zにカーソルのkeyが入っている。
→ 元々入力していた文字をbobptrに入れる。
→ それをBackptr,Nextptrによってポインタを移動させる。

if(z==0xe0){
 z=getch();
 if(z==0x4b){
  bobptr=input.Buffer;
  bobptr=bobptr->BackPtr;
  if(tmp.NextPtr==NULL){
   bobptr=input.EndPtr;
  }
  if(tmp.BackPtr==NULL){
   bobptr=input.StartPtr;
  }
 }
 if(z==0x4d){
  bobptr=input.Buffer;
  bobptr=bobptr->NextPtr;
  if(tmp.NextPtr==NULL){
   bobptr=input.EndPtr;
  }
 }
}


この投稿にコメントする

削除パスワード

No.23588

Re:カーソル移動について
投稿者---まきじ(2005/10/13 09:21:20)


> 12_ の状態からだと一回←を入力すると、12_で二回目で
> 12●_(●には知らない漢字が入る。)となります。

カーソルキー(← →)で、リスト要素を一つ一つ出力したということか・・

左カーソルキーで現在の要素の右側(StartPtr至 = &Buffer[0])
右カーソルキーで現在の要素の右側(EndPtr至)

左カーソルキーは 0xe04b(22475)
右カーソルキーは 0xe04d(22477)

左カーソルキーが押された時、現在の要素の BackPtr を現在の要素にする。
仮に現在の要素を bobptr が指しているのなら bobptr = bobptr.BackPtr
BackPtr が NULL なら何も行わない。
# printf("%a"); とかしたらビープなるかも
右カーソルキーが押された時、現在の要素の NextPtr を 現在の要素にする。(bobptr = bobptr.NextPtr)
NextPtr が NULL なら何も行わない。

以下の様な感じです。

bobptr = StartPtr;
key1 = getch();
key2 = getch();

if(key1 == 0xe0 && key2 == 0x4b){
    if(bobptr.BackPtr != NULL){
        bobptr = bobptr.BackPtr
    }
}else if(key1 == 0xe0 && key2 == 0x4d){
    if(bobptr.NextPtr != NULL){
        bobptr = bobptr.NextPtr
    }
}



この投稿にコメントする

削除パスワード

No.23589

Re:カーソル移動について
投稿者---まきじ(2005/10/13 09:34:42)


># printf("%a"); とかしたらビープなるかも

\a の間違いです。

配列で作ってみました。
#include<stdio.h>
#include<conio.h>

int main(void){
    
    int key1, key2;
    int array[]={-1,0,1,2,3,4,5,6,7,8,9,10,-1};
    int* ptr = &array[1];
    
    for(;;){
        key1 = _getch();
        
        if(key1 == 0x71) break; /* q で終了 */
        if(key1 == 0xe0){
            key2 = _getch();

            if(key2 == 0x4b){ /* 左カーソルキー */
                if(*(ptr - 1) != -1){
                    ptr--;
                    printf("%d\n",*ptr);
                }else printf("\a");
                
            }else if(key2 == 0x4d){ /* 右カーソルキー */
                if(*(ptr + 1) != -1){
                    ptr++;
                    printf("%d\n",*ptr);
                }else printf("\a");
            }
        }else printf("\a");
    }
}



この投稿にコメントする

削除パスワード

No.23574

構造体の初期化について
投稿者---bob(2005/10/12 15:11:40)


カーソル移動と共に教えていただきたいのですが、
下記の構造体にあるstruct InputData Buffer[BUF_LEN+1];
の初期化を教えていただけませんか?
よろしくお願いいたします。

struct InputData {
 char Data;
 struct InputData *BackPtr;
 struct InputData *NextPtr;
};

struct InputBuffer {
 struct InputData *StartPtr;
 struct InputData *EndPtr;
 struct InputData Buffer[BUF_LEN+1];
};



この投稿にコメントする

削除パスワード

No.23587

Re:構造体の初期化について
投稿者---ぽこ(2005/10/13 01:46:43)


>カーソル移動と共に教えていただきたいのですが
別件について質問する時は、別スレッドに分けませんか?

VS.net2003にてコンパイルが通ることを確認。

#define BUF_LEN 2

struct InputData {
    char Data;
    struct InputData *BackPtr;
    struct InputData *NextPtr;
};

struct InputBuffer {
    struct InputData *StartPtr;
    struct InputData *EndPtr;
    struct InputData Buffer[BUF_LEN+1];
};

//こっちを聞きたいのか
struct InputData Buffer[BUF_LEN+1] = {
    {'A', NULL, NULL},
    {'B', NULL, NULL},
    {'N', NULL, NULL},
};

//はたまたこっちを聞きたいのか分からない。
struct InputBuffer hoge = { 
    NULL, 
    NULL, 
    {{'A', NULL,NULL},{'A', NULL,NULL},{'C', NULL,NULL},},
};



この投稿にコメントする

削除パスワード

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