C言語学習記録7 構造体

電話帳プログラム

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

#define MAX 80
#define WORD_MAX 100

struct address // 一人分のアドレスを保存する構造体
{
  char name[WORD_MAX];        // 氏名
  int area_code;              // 市外局番
  char tel_number[WORD_MAX];  // 電話番号
};

struct address_book  // 全員分のアドレスを保存する構造体
{
  struct address ps[MAX];
  int idx;                   // 次の空のアドレス帳の番号を保存
} a_book;

int load_book(void);
int show_address(int num);
int save_book(void);
int menu(void);
int input(char *msg, char *out);

int main(void)
{
  int choice, i;
  char buf[WORD_MAX];

  a_book.idx = 0;

  while(1) {
    choice = menu();
    switch (choice) {
      case 1:
        input("氏名を入力してください:", a_book.ps[a_book.idx].name);
        input("市外局番を入力してください:", buf);
        a_book.ps[a_book.idx].area_code = atoi(buf);
        memset(buf, 0, sizeof(buf)); 
        input("電話番号を入力してください:", a_book.ps[a_book.idx].tel_number);
        a_book.idx++;
        break;
      case 2:
        input("検索する電話番号を入力してください:", buf);
        for (i=0;i<a_book.idx;i++) {
          printf("buf=%s a_book.ps[i].tel_number=%s\n", buf, a_book.ps[i].tel_number);
          if (!strcmp(buf, a_book.ps[i].tel_number)) {
            show_address(i);
          }
        }
        memset(buf, 0, sizeof(buf)); 
        break;
      case 3:
        save_book();
        break;
      case 4:
        load_book();
        break;
      case 5:
        exit(0);
    }
  }

  return 0;
}


int load_book(void)   // ファイルからアドレス帳を読み込む関数
{
  char file_name[] = "address_book";
  FILE *fp;
  if ((fp = fopen(file_name, "rb")) == NULL) {
    return 0;
  }

  if (fread(&a_book, sizeof(a_book), 1, fp) != 1) {
    perror(file_name);
    exit(1);
  }

  if (fclose(fp) == EOF) {
    perror(file_name);
    exit(1);
  }

  return 0;
}



int show_address(int num)  // 引数で指定された1件のアドレスを表示する関数
{
  printf("氏名: %s\n", a_book.ps[num].name);
  printf("市外局番: %d\n", a_book.ps[num].area_code);
  printf("電話番号: %s\n", a_book.ps[num].tel_number);
  return 0;
}

int save_book(void)  // アドレス帳をファイルに保存する関数
{
  char file_name[] = "address_book";
  FILE *fp;
  if ((fp = fopen(file_name, "wb")) == NULL) {
    perror(file_name);
    exit(1);
  }

  if (fwrite(&a_book, sizeof(a_book), 1, fp) != 1) {
    perror(file_name);
    exit(1);
  }

  if (fclose(fp) == EOF) {
    perror(file_name);
    exit(1);
  }

  return 0;
}


int menu(void)   // メニューを表示する関数
{
  char buf[WORD_MAX];
  int num;

  printf("メニューを選択してください\n");
  printf("  1. 氏名と電話番号の入力\n");
  printf("  2. 電話番号の検索\n");
  printf("  3. 電話帳をディスクに保存\n");
  printf("  4. ディスクから電話帳を読み込む\n");
  printf("  5. 終了\n");
  printf(" 選択項目を入力してください: ");

  if (fgets(buf, sizeof(buf), stdin) == NULL) {
    fprintf(stderr, "入力エラー\n");
    exit(1);
  }

  //末尾の改行を削除する
  if (strchr(buf, '\n') != NULL) {
    buf[strlen(buf) - 1] = '\0';
  } else {
    // 改行文字がない場合は、bufのサイズを超えた場合のためエラー終了する
    fprintf(stderr, "一行に入力可能な最大文字数(%d文字)をオーバーしました\n", sizeof(buf) -1 );
    exit(1);
  }

  num = atoi(buf);

  if (( num < 1 ) || ( num > 5 )) {
    fprintf(stderr, "1から5までの数字を入力してください\n");
    exit(1);
  }

  return num;

}


int input(char *msg, char *out)  // メッセージを表示し文字列をキーボード入力させる関数
{

  char buf[WORD_MAX];

  printf(msg);

  if (fgets(buf, sizeof(buf), stdin) == NULL) {
    fprintf(stderr, "入力エラー\n");
    exit(1);
  }

  //末尾の改行を削除する
  if (strchr(buf, '\n') != NULL) {
    buf[strlen(buf) - 1] = '\0';
  } else {
    // 改行文字がない場合は、bufのサイズを超えた場合のためエラー終了する
    fprintf(stderr, "一行に入力可能な最大文字数(%d文字)をオーバーしました\n", sizeof(buf) -1 );
    exit(1);
  }

  strcpy(out, buf);

  return 0;
}