C言語学習記録9 ビットフィールド

  • ビット数を指定して構造体のメンバを割り当てる
  • unsigned(符号なし整数)かint(符号付き整数)のどちらかが使える
#include<stdio.h>

struct test {
  unsigned a: 3;
  unsigned b: 3;
  unsigned c: 2;
};

int main(void) {
  struct test t;
  t.a=3;
  t.b=2;
  t.c=2;

  printf("%d %d %d\n",t.a, t.b, t.c);

  return 0;
}

C言語学習記録8 日時の表示

日時を保持する構造体

 struct tm
{
  int tm_sec;                   /* 秒 [0-60] (1 leap second) */
  int tm_min;                   /* 分 [0-59] */
  int tm_hour;                  /* 時 [0-23] */
  int tm_mday;                  /* 日 [1-31] */
  int tm_mon;                   /* 月 [0-11] */
  int tm_year;                  /* 年 (1900年からの年数)  */
  int tm_wday;                  /* 曜日 (0-6、0が日曜) */
  int tm_yday;                  /* 年初からの日数 [0-365] */
  int tm_isdst;                 /* 夏時間調整フラグ [-1/0/1]*/

#ifdef  __USE_BSD
  long int tm_gmtoff;           /* Seconds east of UTC.  */
  __const char *tm_zone;        /* Timezone abbreviation.  */
#else
  long int __tm_gmtoff;         /* Seconds east of UTC.  */
  __const char *__tm_zone;      /* Timezone abbreviation.  */
#endif
};

システム時刻を取得する関数 time()

#include <time.h>

time_t time(time_t *t);
  • 紀元 (1970年1月1日00:00:00 UTC) からの経過時間を秒単位で返す。エラーの場合は ((time_t)-1) を返し、errno を設定する。
  • time_tはlong int

システム時刻を要素別時刻に変換する関数 localtime()

#include <time.h>

struct tm *localtime(const time_t *timep);

使用例

#include<stdio.h>
#include<time.h>

int main(void)
{
  struct tm *systime;
  time_t t;

  t = time(NULL);
  systime = localtime(&t);

  printf("時刻: %.2d:%.2d:%.2d\n", systime->tm_hour,
          systime->tm_min, systime->tm_sec);
  printf("日付: %.2d/%.2d/%.2d\n", systime->tm_mon+1,
          systime->tm_mday, systime->tm_year + 1900);

結果

時刻: 14:35:48
日付: 08/20/2011

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;
}

C言語学習記録6 図書カードプログラム

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

#define BUFSIZE 256
#define MAX 100
#define SIZE 80

char name[MAX][SIZE];
char book[MAX][SIZE];
char company[MAX][SIZE];
int idx = 0;


int menu(void);
int savefile(void);
int loadfile(void);
int input(char *msg, char *out);
int show_book(int num);

int main(void) {

  int choice;
  char word[SIZE];
  int i;

  loadfile();

  while(1){
    choice = menu();
    switch (choice) {
      case 1:
        input("著者名を入力してください:", name[idx]);
        input("書籍名を入力してください:", book[idx]);
        input("出版社を入力してください:", company[idx]);
        idx++;
        break;
      case 2:
        input("検索する著者名を入力してください:", word);
        for (i=0;i<idx;i++) {
          if (!strcmp(word, name[i])) {
            show_book(i);
          }
        }
        break;
      case 3:
        input("検索する書籍名を入力してください:", word);
        for (i=0;i<idx;i++) {
          if (!strcmp(word, book[i])) {
            show_book(i);
          }
        }
      case 4:
        savefile();
        break;
      case 5:
        exit(0);
    }
  }

  return 0;
}

int show_book(int num) {
  printf("著者名: %s\n", name[num]);
  printf("書籍名: %s\n", book[num]);
  printf("出版社: %s\n", company[num]);
  return 0;
}


int input(char *msg, char *out) {

  char buf[SIZE];

  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;
}

int savefile(void) {
  char file_name[] = "catalog";
  FILE *fp;
  if ((fp = fopen(file_name, "wb")) == NULL) {
    perror(file_name);
    exit(1);
  }

  if (fwrite(&idx, sizeof(idx), 1, fp) != 1) {
    perror(file_name);
    exit(1);
  }
  if (fwrite(name, sizeof(name), 1, fp) != 1) {
    perror(file_name);
    exit(1);
  }
  if (fwrite(book, sizeof(book), 1, fp) != 1) {
    perror(file_name);
    exit(1);
  }
  if (fwrite(company, sizeof(company), 1, fp) != 1) {
    perror(file_name);
    exit(1);
  }


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

  return 0;
}

int loadfile(void) {
  char file_name[] = "catalog";
  FILE *fp;
  if ((fp = fopen(file_name, "rb")) == NULL) {
    return 0;
  }

  if (fread(&idx, sizeof(idx), 1, fp) != 1) {
    perror(file_name);
    exit(1);
  }
  if (fread(name, sizeof(name), 1, fp) != 1) {
    perror(file_name);
    exit(1);
  }
  if (fread(book, sizeof(book), 1, fp) != 1) {
    perror(file_name);
    exit(1);
  }
  if (fread(company, sizeof(company), 1, fp) != 1) {
    perror(file_name);
    exit(1);
  }

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

  return 0;

}


int menu(void) {

  char buf[BUFSIZE];
  int num;

  printf("図書カードカタログ:\n");
  printf(" 1.入力\n");
  printf(" 2.著者名による検索\n");
  printf(" 3.書名による検索\n");
  printf(" 4.ファイルに保存\n");
  printf(" 5.終了\n");

  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;


}