双方向リストのプログラミングのチェック
指定したファイルを読み込み、一行ずつ構造体に保存し、表示させる。その後、キーボードから指定した行を削除し、処理後の結果を表示させる・・・といったプログラミングを作成しています。
通常の表示の部分はできましたが、後は指定した行の削除の部分ができません。
あらかじめHPで調べてあるので、削除するときは、その削除したい行をまたいで、前後のリストを繋げるといった概念的なのは大体理解できました。
自分なりに考えたり調べて、下のように打ちました。
ですが、キーボードから入力した値をどう関数に対応させていくのか、
delete_head,delete_tailの関数の部分に出る、head,tailは使えない的なエラーの対処の仕方がわからなく、詰まってます。
アドバイス、他にも直す場所等ありましたらお願いします。
#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 *);
void delete_head(void);
void delete_tail(void);
void delete(Num *target);
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);
printf("input number\n");
scanf("%d",&j);
p=head;
for(i=0;i<=j;i++);{
p=p->next;
}
if(p==head){
delete_head(void);
}
else if(p==tail){
delete_tail(void);
}
else{
delete(p->prev);
}
p=head;
while(p!=tail){
printf("%s\n",p->line);
p=p->next;
}
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 ;
}
void delete_head(void){
Num *second=head->next;
if(secound==NULL){
free(head);
head=NULL;
tail=NULL;
}
else{
second->prev=NULL;
free(head);
head=second;
}
}
void delete_tail(void){
Num *second_last=head->prev;
if(second_last==NULL){
free(tail);
head=NULL;
tail=NULL;
}
else{
second_last->next=NULL;
free(tail);
tail=second_last;
}
}
void delete(Num *target){
Num *after_target;
Num *before_target;
after_target=target->next;
before_target=target->prev;
after_target->prev=target->prev;
before_target->next=target->next;
free(target);
}
お礼
episteme 様 お忙しい中、お答えいただきありがとうございました。今までわからなかったのですが、よくわかりました。
補足
すいません、確認の意味でお聞きします。 p->prev = c->prev; p->next = c; c->prev->next = p; c->prev = p; p->prev->next = p->next; p->next->prev = p->prev; 上記のそれぞれは、そこの部分を表しているのですか? なんとなく考えているうちにおかしくなってしまうんです。たぶん、そこが把握できてないのだと思います。 ご指導よろしくお願いします。