[TA] C言語: 課題プログラムの修正2

[TA] C言語: 課題プログラムの修正2 - TODO

提出してもらったプログラム

以下に提出してもらったプログラムのソースコードを示します.

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

typedef struct {
   char *name;
   int age;
} Card;

typedef struct _tree {
   Card card;
   struct _tree *next;
} Tree;

Card meibo[] = {
   {"Takahashi", 14},
   {"Kobayashi", 15},
   {"Hosokawa",  17},
   {"Sugimoto",  18},
   {"Sawai",     19},
   {"Itou",      20},
   {"Kawai",     22},
   {"Ishikura",  24},
   {"Oda",       25},
   {"Nakamura",  28}
};

int main(void) {
   Tree* root = NULL;
   Tree* p;

   int i,age;
   int n = sizeof(meibo)/sizeof(meibo[0]);

   for(i = n-1;i >= 0;i--) {
      p=(Tree*)malloc(sizeof(Tree));
      p->card = meibo[i];
      p->next = root;
      root = p;
   }

   printf("age? : ");

   while (scanf("%d",age) != EOF) {
      p = root;
      while(p != NULL) {
         if (age == p->card.age) break;
         p = p->next;
      }

      if(p != NULL) {
         printf("not found.");
      } else {
         printf("found.\n");
         printf("%s &d\n",p->card.name,p->card.age);
      }

   }

   return(0);
}

セグメンテーション違反の原因になっているのは,変数ageにscanfを用いて値を格納するとき,&ageでアドレスを渡さなければいけないのに,値を渡してしまっているからです.

修正案

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

typedef struct {
   char *name;
   int age;
} Card;

typedef struct _tree {
   Card card;
   struct _tree *next;
} Tree;

Card meibo[] = {
   {"Takahashi", 14},
   {"Kobayashi", 15},
   {"Hosokawa",  17},
   {"Sugimoto",  18},
   {"Sawai",     19},
   {"Itou",      20},
   {"Kawai",     22},
   {"Ishikura",  24},
   {"Oda",       25},
   {"Nakamura",  28}
};

int main(void) {
   Tree* root = NULL;
   Tree* p;

   int i,age;
   int n = sizeof(meibo)/sizeof(meibo[0]);

   for(i = n-1;i >= 0;i--) {
      p=(Tree*)malloc(sizeof(Tree));
      p->card = meibo[i];
      p->next = root;
      root = p;
   }

   printf("age? : ");

   while (scanf("%d", &age) != EOF) {
      p = root;
      while(p != NULL) {
         printf("  process: compare %d with %s's age %d\n", age, p->card.name, p->card.age);
         if (age == p->card.age) break;
         p = p->next;
      }

      if(p == NULL) {
         printf("not found.\n");
      } else {
         printf("found.\n");
         printf("%s is %d years old.\n",p->card.name,p->card.age);
      }

      printf("age? : ");
   }

   return(0);
}

変更を加えた箇所

  • scanfを用いてageに値を格納するとき,ageではなく&ageを引数として与えるようにした
  • 見つかったかどうかの判定で「P!=NULL」のときに「見つからない」としていたが,これだと意味が逆なので変更した
  • while文の最後に「age? : 」と問い合わせを表示する処理を加え,2回目以降の探索時にも表示がなされるようにした
[Good Job!]