- 締切済み
双方向リスト 指定行の削除について
現在、双方向リストを使用したプログラミングを作成しています。 コマンドラインから指定したファイルを読み込み、各行の文字列を データとする構造体に記録する。ひとつの構造体に1行の文字列を 記録し、それらの構造体を、行の順番に従ってつながった双方向 リスト構造として、ファイル全体を記録する。 さらに、キーボードから指定した行番号の行を削除する処理を行った後に、再度リストを順方向に表示する・・・といった内容です。 文字列を順、逆順ともに表示できるところまではできたのですが、肝心の行の削除の仕方がわからなくて、困ってます。 具体的には、入力した値をどのように関数に当てはめるのか、つまり行削除の関数の処理をどうすればよいのかがわかりません。 ↓は途中のプログラムです。 fcloseの上にキーボード入力と処理後の表示のコマンド、 一番最後のほうにリスト削除用の関数を入力するのだと思いますが・・・。 OSはLinuxです。 回答宜しくお願いします。 #include<stdio.h> #include<stdlib.h> #define LINE 1000 typedef struct num{ char line[LINE]; struct num *next; struct num *prev; }Num; void normal(Num **,Num **,char *); void reverse(Num *,Num *,char *); int main(int argc,char *argv[]) { FILE *fp; char line[LINE]; int i=0,j; Num *head,*tail,*p; head=NULL; tail=NULL; fp=fopen("test.txt","r"); if(fp==NULL){ fprintf(stdout,"File not found.\n"); exit(1); } while(fgets(line,LINE,fp)!=NULL) { normal(&head,&tail,line); } p=head; while(p!=tail){ printf("%s\n",p->line); p=p->next; } printf("%s\n",p->line); p=tail; while(p!=head){ printf("%s\n",p->line); p=p->prev; } printf("%s\n",p->line); fclose(fp); return 0; } void normal(Num **s,Num **e,char *g){ Num *tmp; int i; if(*s==NULL){ *s=(Num *)malloc(sizeof(Num)*1); (*e)=(*s); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ (*s)->line[i]=g[i];} (*s)->next=*e; (*s)->prev=*s; } else{ tmp=(Num *)malloc(sizeof(Num)*1); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ tmp->line[i]=g[i];} tmp->prev=(*e); (*e)->next=tmp; tmp->next=(*e); (*e)=tmp; } return ; } void reverse(Num *kan1,Num *kan2,char *g){ Num *tmp; int i; tmp=(Num *)malloc(sizeof(Num)*1); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ tmp->line[i]=g[i];} tmp->prev=kan1; kan1->next=tmp; tmp->next=kan2; kan2->prev=tmp; return ; }
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- necomimi3
- ベストアンサー率40% (124/307)
削除の処理ですが 指定行までNEXTを使って進み削除対象へのNEXTポインタを その次のNum行のポインタにつなぎ換え、削除行の次行のPREVポインタも 削除行の前行のNum行を指すようにすれば良いと思います。 切り離された削除行のfreeはお忘れなく(^w^
- asuncion
- ベストアンサー率33% (2127/6289)
> 一番最後のほうにリスト削除用の関数を入力するのだと思いますが・・・。 そういう順序はどちらでもいいのではないでしょうか。 コマンドライン引数で指定したファイルを読み取って 双方向リストを作成するところまでは、必ず行ないますよね。 その後は、下記のようなメニューを表示して、処理ごとの関数を 実行すればよいと思います。 メニューを表示するところはループを構成しておいて、 1)~3)の処理を何度でも繰り返せるようにしておくとよいでしょう。 【メニューの一例】 1)行の順表示(normal関数を実行する) 2)行の逆表示(reverse関数を実行する) 3)行の削除(この関数は、まだない) 4)終了(必要があればファイルに書き戻して、プログラムを終了する)
お礼
順序は関係ないのですか。わかりました。 ただ、削除の関数の内容がまだ分からない状態です・・・。
お礼
リストを削除して、順序を変えるという概念は大体理解しています。freeを入れることはわかかりませんでしたので、ちゃんと入れるようにします。