• 締切済み

C言語の自己参照型プログラムについて

#include <stdio.h> #include <string.h> #include <stdlib.h> struct list { int key; /* キー */ char name[20]; /* 名前 */ struct list *next; /* 次のデータへのポインタ */ }; struct list *add_list(int key, char *name, struct list *head); void show_list(struct list *p); void free_list(struct list *p); int main(void) { struct list *head; /* 先頭ポインタ */ char name[20]; int key = 0; head = NULL; /* 先頭ポインタにNULLを設定 */ printf("キーと名前(MAX:19文字)を入力(終了:CTRL+Z)\n"); while (scanf("%d %s", &key, name) != EOF) { /* リストにデータを登録 */ head = add_list(key, name, head); } /* リストの表示 */ show_list(head); /* リストの開放 */ free_list(head); return 0; } /*** リストにデータを登録 ***/ struct list *add_list(int key, char *name, struct list *head) { struct list *p; /* 記憶領域の確保 */ if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) { printf("malloc error\n"); exit(EXIT_FAILURE); } /* リストにデータを登録 */ p->key = key; strcpy(p->name, name); /* ポインタのつなぎ換え */ p->next = head; /* 今までの先頭ポインタを次ポインタに */ head = p; /* 新たな領域を先頭ポインタに */ return head; } /*** リストの表示 ***/ void show_list(struct list *p) { while (p != NULL) { /* 次ポインタがNULLまで処理 */ printf("%3d %s\n", p->key, p->name); p = p->next; } } /*** リストの開放 ***/ void free_list(struct list *p) { struct list *p2; while (p != NULL) { /* 次ポインタがNULLまで処理 */ p2 = p->next; free(p); p = p2; } } これを実行すると、 新しく入力された順にリストが表示されます。 そうではなく、キーの昇順に表示したいです。 どなたかそのように実行できるようにプログラムを書き換えてくれませんか? 図々しいですがよろしくお願いいたします。m(_ _)m

みんなの回答

  • hrsmmhr
  • ベストアンサー率36% (173/477)
回答No.2

修正します memcmpの不等号は逆です あと最初の判定ででるとp3が不定になりますのでnullをいれて判定してheadにつないでください

  • hrsmmhr
  • ベストアンサー率36% (173/477)
回答No.1

add_listのポインタのつなぎかえで for(p2=head; (memcmp(p, p2, p->key)<0)&&(p2!=NULL); p2=p2->next){ p3=p2; } p3->next=p; p->next=p2; でよいかと思います。p2とp3は宣言してください

関連するQ&A

  • 難しい・・・

    待ち行列への挿入と削除をするプログラムです。 先頭のkeyはそれぞれ I…単語を待ち行列に追加 D…単語を待ち行列から削除 P…現在の待ち行列に並んでいる要素を表示 Q…終了 を意味し、 入力例として I lose I eow D dummy P dummy I pop P dummy Q dummy のようなものを入力した時 eow eow pop のように表示されるようにしたいと思っています。 しかしできません>< プログラムは以下の通りです。 #include <stdio.h> #include <string.h> #include <stdlib.h> struct q{ char key; char word; struct q *next; /* 次のデータへのポインタ */ }; struct q *add_q(char key, char *name, struct q *head); void show_q(struct q *p); void free_q(struct q *p); int main(void) { struct q *head; /* 先頭ポインタ */ char word[20]; char key = 0; head = NULL; while(1){ scanf("%c %s",&key,word); switch(key){ case 'I': head=add_q(key, word, head); case 'P': show_q(head); case 'D': free_q(head); case 'Q': exit(1); default: printf("This is unexpected command\n"); }} return 0; } /*** リストにデータを登録 ***/ struct q *add_q(char key, char *word, struct q *head) { struct q *p; /* 記憶領域の確保 */ if ((p = (struct q *) malloc(sizeof(struct q))) == NULL) { printf("malloc error\n"); exit(EXIT_FAILURE); } /* リストにデータを登録 */ p->key = key; strcpy(p->word,word); /* ポインタのつなぎ換え */ p->next = head; /* 今までの先頭ポインタを次ポインタに */ head = p; /* 新たな領域を先頭ポインタに */ return head; } /*** リストの表示 ***/ void show_q(struct q *p) { while (p != NULL) { /* 次ポインタがNULLまで処理 */ printf("%3d %s\n", p->key, p->word); p = p->next; } } /*** リストの開放 ***/ void free_q(struct q *p) { struct q *p2; while (p != NULL) { /* 次ポインタがNULLまで処理 */ p2 = p->next; free(p); p = p2; } }

  • C言語のプログラム

    以下のプログラムはハッシュテーブルを用いて文字列を探すプログラムなのですが、コンパイル時にセグメントエラーとなってしまいます。プログラム中に誤った箇所があれば教えて頂きたいです。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASHSIZE 10 #define MAX_LEN 64 #define N_WORDS 4 struct list { char word [MAX_LEN]; struct list *next; }; struct list *hash_table[HASHSIZE]; char colors[N_WORDS][MAX_LEN] = {"red", "blue", "green", "yellow"}; void my_strcpy(char* a, const char* b) { int i = 0; while(*b != '\0'){ *(a+i) = *(b+i); i++; } *(a+i) = '\0'; } int hash(char *key) { int hashval = 0; while (*key != '\0') { hashval += *key; key++; } return (hashval % HASHSIZE); } int find_word (char *key) { struct list *p; for (p = hash_table[hash(key)]; p != NULL; p++) if (strcmp(key, p->word) == 0) return 1; return 0; } void init_hash_table() { int i, hashvalue; struct list *p, *q; for (i = 0; i < HASHSIZE; i++) { hash_table[i] = NULL; } for (i = 0; i < N_WORDS; i++) { if ((find_word(colors[i])) == 0){ p = (struct list *)malloc(sizeof(struct list)); my_strcpy(p->word, colors[i]); hashvalue = hash(colors[i]); if (hash_table[hashvalue] = NULL) { hash_table[hashvalue] = p; p->next=NULL; } else { q = hash_table[hashvalue]; while (q->next != NULL) q = q->next; q->next = p; p->next=NULL; } } } } void main(void) { init_hash_table(); printf("result = %d\n", find_word("red")); }

  • このソースの意味を教えてください

    構造体を使ったリストを理解するためのソースで http://www9.plala.or.jp/sgwr-t/c/sec15-5.html のページに以下の関数が書いてありました。 自分はreturn p;とするのが自然であって、head = p;の意味が分かりません。それが不要な処理であるように思えます。 return head;としているのでその前にhead = p;は必要な処理ですが、無駄であって意味が無いように見えましたが、そのように書くのが自然なのでしょうか? head = p;の右に書いてあるコメントもおかしいと思うのですが、皆さんにはそのページのソースのその部分はコメントも含めて不自然さを感じないでしょうか? /*** リストにデータを登録 ***/ struct list *add_list(int key, char *name, struct list *head) {   struct list *p;   /* 記憶領域の確保 */   if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) {     printf("malloc error\n");     exit(EXIT_FAILURE);   }   /* リストにデータを登録 */   p->key = key;   strcpy(p->name, name);   /* ポインタのつなぎ換え */   p->next = head;  /* 今までの先頭ポインタを次ポインタに */   head = p;     /* 新たな領域を先頭ポインタに */   return head; }

  • リストの削除について(構造体)

    リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #include<stdio.h> #include<malloc.h> #include<string.h> struct list{ char name[20]; int age; struct list *next; }; void main(void) { struct list *head, *p, *n, *old; char key[20]; /*ダミーノード作成*/ head = (struct list*)malloc(sizeof(struct list)); old = head; while(p = (struct list*)malloc(sizeof(struct list)), printf("name age入力\n"), scanf("%s %d", p -> name, &p -> age) != EOF){ old -> next = p; old = p; } free(p); old -> next = NULL; p = head -> next; printf("変更前リスト\n"); while(p != NULL){ printf("name:%s age:%d\n",p -> name, p -> age); p = p -> next; } printf("削除key入力(name)\n"); gets(key); n = head; while(n != NULL){ old = n; n = n -> next; //printf("n -> name %s\n", n -> name); if(strcmp(n -> name, key) == 0){ printf("%s削除\n", key); //printf("n -> name %s old -> name %s\n", n -> name, old -> name); old -> next = n -> next; } } p = head -> next; printf("変更後リスト\n"); while(p != NULL){ printf("name:%s age:%d\n", p -> name, p -> age); p = p -> next; } }

  • リストの作成と出力(C言語)

    こんにちは<_ _> リストの問題についてなのですが出力と逆順に出力するプログラムで headと前のデータの間に新しいデータを追加するように作ったのですが 入力した値が帰ってきません・・・ http://www9.plala.or.jp/sgwr-t/c/sec15-5.html などを見て見ましたが原因がいまいちよくわかりません。 どなたか教えてください おねがいします<_ _> #include<stdio.h> #include<malloc.h> struct tfield{ char name[20]; char tel[20]; struct tfield *pointer; }; struct tfield *talloc(void); int main(void) { struct tfield *head,*p; char buffer[BUFSIZ]; head=NULL; while(1){ p=talloc(); if(scanf("%s",buffer) == EOF){ break; strcpy(p->name, buffer); } if(buffer == "^Z")break; printf(" "); if(gets(buffer) == EOF){ if(scanf("%s",buffer) == EOF){ break; strcpy(p->tel, buffer); } p->pointer=head; /*今までの先頭ポインタを次のポインタに*/ head=p; } p=head; while(p!=NULL){ printf("%6s %s\n",p->name,p->tel); p=p->pointer; } return 0; } struct tfield *talloc(void) /*記憶領域の取得*/ { return (struct tfield *)malloc(sizeof(struct tfield)); } 変数は変えるなとのことです。 あと、 「name tel name tel name tel ^z name tel name tel name tel」 と表示したいのですがCtrl+zを二回押さないとできません><、 当方プログラム1ヶ月の初心者です ご指導どうかよろしくお願いします<_ _>

  • C言語 リスト

    (1) /* list.c */ #include <stdio.h> #include <stdlib.h> struct node { int num; struct node *next; }; main() { struct node *head, *p; int x; head = NULL; while(scanf("%d",&x) != EOF) { p = (struct node *)malloc(sizeof(struct node)); p->num = x; p->next = head; head = p; } // リストの要素のnumの値を先頭から順に表示する p=head; while(p!=NULL) { printf("%d\n" ,p->num); p = p->next; } } (2) struct node *q; q = head; while(q->next != NULL) q = q->next; (1)を(2)を使い新しいノードをリストの最後に追加するようにしたいのですが どう書いたら良いのか教えていただきたいです

  • 【C言語】構造体内の領域解放(free)の仕方

    教えてGoo運営側に内容チェックされているため再度内容を変更し質問させていただきます。 http://okwave.jp/qa/q8080757.html (ダンプを書いたのがまずかったかもしれないので、ここでは削除します。) <プログラムで実行したいこと> ・簡単なリストを作成 ・リストを構成する構造体のメンバはchar*などのメンバがあり、  特に、char*にstrdupにて文字列をコピーする。(正確には文字列のポインタをコピーする。) ・作ったリストをプリントする。 ・領域を確保する。 下記のソースで動くと思ったのですが、領域のfreeでうまくいきません。 どうもない領域をfreeしているようなのです。それがなぜかわかりません。 *** glibc detected *** ./a.out: free(): invalid pointer: 0x00000000020eb030 *** どうしたら、解決するのか、どこが悪いのかご指摘いただけないでしょうか。 以下、私が書いたソースになります。 #include<stdio.h> #include<stdlib.h> #include<string.h> struct word { struct word *next; char *st; int *line_no; int line_cnt; }; struct word *head; void Add_List(char *buf,int no){ struct word* node = malloc(sizeof(struct word*)); struct word* crnt; /*nodeの準備*/ node->next = NULL; //node->st = strdup(buf); node->st = malloc(sizeof(char)*10); strcpy(node->st,buf); node->line_no = malloc(sizeof(int*)); node->line_no[0] = 1; node->line_cnt= 1; if(head == NULL) { head = node; } else { crnt = head; while( crnt->next != NULL) { crnt = crnt->next; } crnt->next = node; } } void printlist(){ struct word *crnt = head; while( crnt != NULL ) { printf("%s\n",crnt->st); crnt = crnt->next; } } int main(){ head = NULL; char buf1[] = {'A','B','C','D','E','\0'}; char buf2[] = {'F','G','H','I','J','\0'}; char buf3[] = {'K','L','M','N','O','\0'}; Add_List(buf1,1); Add_List(buf2,1); Add_List(buf3,1); printlist(); /*この部分がうまくいかない*/ printf("%s\n",head->st); printf("%x \n",head->st); free(head->st); /*********************/ }

  • このプログラムのポインタを配列に変換したいんですけど

    C言語初心者です。助けてください。 途中までがんばったのですがどうしてもできません。問題はこの構造体の*name→name[25],*email→email[30]に変換させたいのですが、そのまま変換すると左辺値が必要や移植性のないポインタ変換などのエラーが出てしまいます。どうすればいいですか?教えてください。あと関数getlineと構造体は変えないでください。(指定した部分は除く) このプログラムは名前、メールアドレス、年齢を保存していき-1を入力した時出力されるというものです。 よろしくお願いします。 入力例 10 hakata abc@・・・ 12 yokohama dfg@・・・ -1 -1 -1 出力例 -1 -1 -1 12 yokohama dfg@・・・ 10 hakata abc@・・・ #include <stdio.h> #include<stdlib.h> struct node { char *name; char *email; int age; struct node *next; } heap[100], *hp = heap; void getline(char *s,int n) { int c; while(--n>0&&((c=getchar())!=EOF && c!='\n')) *s++=c; *s='\0'; } char* dupstr(char* strg) { char* newstr; newstr=(char*)malloc(sizeof(char)*strlen(strg)); strcpy(newstr,strg); return newstr; } struct node *new(int n ,char* a, char* b) { hp->age=n; hp->email=a; hp->name=b; hp->next=NULL; return hp++; } struct node *add(struct node *p, struct node *q) { q->next=p; p=q; return p ; } void print_list(struct node *p) { while (p != NULL) { printf("%d ", p->age); printf("%s ", p->name); printf("%s ", p->email); p=p->next; } printf("\n"); } main() { int age,p; char buf[80],a[80],b[80],*email,*name; struct node *root=NULL; while(getline!=NULL) { getline(buf,sizeof(buf)); age=atoi(buf); getline(b,sizeof(b)); getline(a,sizeof(a)); email=dupstr(b); name=dupstr(a); root=add(root,new(age,email,name)); if(age==-1) break; } print_list(root); }

  • 終了条件Ctrl+zについて,結果表示ついて(C言語)

    こんにちは<_ _> 自己参照構造体に関する問題を解いています。 入力したデータとは逆順につながったリストを作成するという 問題で、結果はともかく逆順表示に出力できましたが 微妙なところでNGが出ています。 まず、 (1)「Ctrl+z」一回で終了しなければならない    以下のプログラムでは二回Ctrl+zを入力しないと    入力が終了できません。 (2)入力時並列させること    以下のプログラムでは入力時    「name tell name tell ・ ・     Ctrl+z」    と入力しなければなりませんが 「name tell name tell」 という風に入力しなければなりません・・・ (3)変数を変化、増減させてはならない     並列させるために変数増やそうと思ったら     bufferだけでやらなければならないみたいです・・・ 三時間ぐらい調べて悩みましたがうまくいきませんでした どうしたら以上のようにできるのかご指導、ご鞭撻のほどを どうかよろしくお願いします<_ _> #include<stdio.h> #include<malloc.h> struct tfield{ char name[20]; char tel[20]; struct tfield *pointer; }; struct tfield *talloc(void); int main(void) { struct tfield *head,*p; char buffer[BUFSIZ]; head=NULL; while(1){ p=talloc(); if( p == NULL ){ printf( "メモリを確保できません。\n" ); _exit( 0 ); } if(scanf("%s",&buffer)==EOF){ break; strcpy(p->name, buffer); } buffer=0; if(scanf("%s",&buffer)==EOF){ break; strcpy(p->tel, buffer); } p->pointer = head; head = p; } if(head != NULL){ p=head; while(p!=NULL){ printf("%6s %s\n",p->name,p->tel); p=p->pointer; } } return 0; } struct tfield *talloc(void)    /*記憶領域の取得*/ { return (struct tfield *)malloc(sizeof(struct tfield)); }

  • C言語の構造体についてなんですが。

    struct LIST {     struct Num* number;     struct LIST* next;/* 次の要素へのポインタ */ }*root; struct Num{     int a;     struct Num* next; /* 次の要素へのポインタ */ }*numroot; と構造体を定義したときに、 main(){     struct LIST *p;     for(p = root; p != NULL; p = p->next) ; } とすれば、pの先頭からNULLまでを参照していくことは分かるんですが、pのnumberの先頭からNULLまでの参照方法(プログラムのfor文の記述方法)がイマイチわかりません。つまり、構造体の構造体をどのように参照するかということです。 これを実現したい理由は、構造体内での数の格納を配列(固定長)ではなく可変長で格納したいからです。 分かる方は解答をお願いします。

専門家に質問してみよう