リスト構造によるアドレス帳の作成
Posted: 2011年12月11日(日) 12:01
この掲示板を始めて利用させていただきます。
C言語の勉強をしているのですが、アドレス帳を作るプログラムで詰まってしまいました。
課題丸投げという風になってしまって恐縮ですがよろしくお願いします。
プログラムは、リスト構造を使って名前・住所・電話番号・メールアドレスのデータを持った構造体のアドレス帳を作ること。
その際、txtなどのファイルから読み込み、データの追加・削除・参照・ソート(名前か電話番号を選んでソートする)ができる。
そして、データを書き換えた場合は新しいファイルに書き込むというものです。
こちらが途中のプログラムになります。
/*address.csvの中身*/
sato,tokyo,02018179484,hogehoge@docomo
suzuki,saitama,02037829163,prog@docomo
saito,yamanashi,03019295433,ruby_love@docomo
kato,kanagawa,02012345678,java@docomo
最終的には関数それぞれ別ファイルにわけたいので、先頭アドレスのheadを引数にしました。
追加と参照は出きるのですが、削除が上手くいかないのとソートの実装が分からない状況です。
双方向リスト構造というものを使うべきなのでしょうが、よく分からず詰まってしまいました。
雑なコードに長文失礼しました。
アドバイス等よろしくお願いします。できればソースを載せていただくと大変ありがたいです。
C言語の勉強をしているのですが、アドレス帳を作るプログラムで詰まってしまいました。
課題丸投げという風になってしまって恐縮ですがよろしくお願いします。
プログラムは、リスト構造を使って名前・住所・電話番号・メールアドレスのデータを持った構造体のアドレス帳を作ること。
その際、txtなどのファイルから読み込み、データの追加・削除・参照・ソート(名前か電話番号を選んでソートする)ができる。
そして、データを書き換えた場合は新しいファイルに書き込むというものです。
こちらが途中のプログラムになります。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct address{
//アドレス帳のデータ
char name[32];
char addre[128];
char number[12];
char mail[64];
struct address* next; //次の要素へのポインタ
};
/*プロトタイプ宣言*/
void data_show(struct address* head);
void data_add(struct address*head);
void data_delete(struct address*head);
void data_sort(struct address*head);
void data_write(struct address* head);
int main(void){
struct address* head=NULL,*p;
FILE* fp;
int c;
fp = fopen("address.csv","r");
if(fp==NULL){
printf("file not open\n");
exit(1);
}
char ch[512];
while(fscanf(fp,"%s",ch)!=EOF){
p = (struct address*)malloc(sizeof(struct address));
char* token=",";
strcpy(p->name ,strtok(ch,token));
strcpy(p->addre ,strtok(NULL,token));
strcpy(p->number ,strtok(NULL,token));
strcpy(p->mail ,strtok(NULL,token));
p->next = head;
head = p;
}
p = head;
printf("\n");
fclose(fp);
int select;
while(select != 0){
printf("1:ソート 2:削除 3:追加 4:参照 0:終了\nメニューを選択してください:");
scanf("%d",&select);
switch(select){
case 1:
data_sort(head);
break;
case 2:
data_delete(head);
break;
case 3:
data_add(head);
break;
case 4:
data_show(head);
break;
case 0:
printf("終了します\n");
break;
default:
printf("もう一度選択してください\n");
break;
}
}
return 0;
}
//データの追加する関数
void data_add(struct address* head){
struct address* p, *q, *new;
char new_name[32];
char new_addre[128];
char new_number[12];
char new_mail[64];
printf("追加する要素を入力してください");
printf("名前:"); scanf("%s",new_name);
printf("住所:"); scanf("%s",new_addre);
printf("電話番号:"); scanf("%s",new_number);
printf("メールアドレス:"); scanf("%s",new_mail);
p = head->next;
q = head;
while(p != NULL){
q = p;
p = p->next;
}
new = (struct address*)malloc(sizeof(struct address));
strcpy(new->name,new_name);
strcpy(new->addre,new_addre);
strcpy(new->number,new_number);
strcpy(new->mail,new_mail);
new->next = p;
q->next = new;
q = head;
data_write(q);
}
void data_delete(struct address* head){
char name[32];
struct address* p, *before;
printf("アドレスを削除します\n名前を入力してください:");
scanf("%s", &name);
p = head;
int flag = 0;
while(p != NULL && strcmp(p->name,name)!=0){
before = p;
p = p->next;
flag = 1;
printf("a\n");
}
printf("%s\n",p->name);
if(flag==0 && strcmp(p->name,name) == 0){
before = p;
p = p->next;
before = NULL;
}
else if(p == NULL){
printf("アドレスに登録されていません\n");
}else{
before->next = p->next;
p = head;
printf("アドレスを削除しました\n\n");
data_write(p);
}
}
//データを参照する関数
void data_show(struct address* head){
struct address* p = head;
while(p){
printf("%s,%s,%s,%s\n",p->name,p->addre,p->number,p->mail);
p = p->next;
}
printf("\n");
}
//データソート関数
void data_sort(struct address* head){
struct address* p,*before,*after;
p = head;
after = head->next;
if(strcmp(p->name,after->name) > 0){
p = after;
p->next = head;
p->next->next = after->next;
}
before = p;
p = p->next;
after = p->next;
while(before){
before = p;
p = p->next;
after = p->next;
}
printf("ソートしました\n");
}
//ファイルに書き込む関数
void data_write(struct address* p){
FILE* fp2;
struct address* tmp;
fp2 = fopen("new_address.csv","w");
if(fp2==NULL){
printf("file not open\n");
exit(1);
}
while(p){
fprintf(fp2,"%s,%s,%s,%s\n",p->name,p->addre,p->number,p->mail);
p = p->next;
}
fclose(fp2);
}
/*address.csvの中身*/
sato,tokyo,02018179484,hogehoge@docomo
suzuki,saitama,02037829163,prog@docomo
saito,yamanashi,03019295433,ruby_love@docomo
kato,kanagawa,02012345678,java@docomo
最終的には関数それぞれ別ファイルにわけたいので、先頭アドレスのheadを引数にしました。
追加と参照は出きるのですが、削除が上手くいかないのとソートの実装が分からない状況です。
双方向リスト構造というものを使うべきなのでしょうが、よく分からず詰まってしまいました。
雑なコードに長文失礼しました。
アドバイス等よろしくお願いします。できればソースを載せていただくと大変ありがたいです。