3 STEP 2(検索)

つぎのステップは電話帳のデータベースから、目的のデータを検索するプログラムである。

3.1 動作内容

氏名を検索する場合、"名字"と"名字 名前"の場合がある。その両方に対応するためには、 教科書に書いてあるとおり、 のようなことが必要である。すなわち、空白を上手に使って、氏名や名字の区切りに使うのであ る。詳細については、教科書のp.333〜334を見よ。

また、氏名をキーボードから1度に読み込み場合、空白付きで読み込む必要がある。その ためには、getsあるいはfgetsを使うことになる。scanfを使うことも考 えられるが、その場合は空白が読み込めないのでその処理が必要である。それぞれは、

gets
1行空白付きで読み込める。また、キーボードからデータを入力したときの最後の改行 (\n)は付かない。ただし、配列より多くのデータがキーボー ドから送られるとそれを越えてメモリーに格納しようとするので問題が発生することが ある。
fgets
1行を空白付きで読み込める。しかし、データを入力したときの最後 の改行も配列の中に残る。この処理が必要である。
scanf
名字と名前の間の空白が読み込めない。この処理が必要である。
のような得失があり、どれを使うか考えなくてはならない。ここでは、fgetsを使っ たので、以降はそれに仮定して説明する。ただし、諸君はどれを使っても良いが、それな りの処理をする必要がある。

この空白を考慮すると、電話帳のデータベースを検索するプログラムには、次のような動 作が必要である。

  1. 検索する名前の読み込みと空白の追加
    • キーボードから1行を読み込む
    • 改行を空白に変更
  2. 比較する文字数(空白付き)のカウント
  3. データベースファイルのオープン
  4. 人数分、データベースから読み込み、検索する文字列と比較する。そして、一致 したら、名前と電話番号を表示する。
    • キーボードから1行を読み込む
    • 格納されたデータの最後に空白を追加
      • "\0"を空白に変更
      • "\0"を追加
    • 電話番号の読み込み
    • データベースから読み込んだ氏名と検索する名前の比較。もし、一致すれ ば、氏名と電話番号を表示する。
  5. ファイルのクローズ

3.2 プログラム例

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

	int main(void)
	{
	  FILE *read_list;
	  char r_shimei[16][64];
	  char r_tel[16][16];
	  char search_name[32];
	  int compare_char;
	  int i;

	  /*---- 検索する名前の読み込みと改行処理 ---- */
  
	  printf("\n\t検索したい人の名前を入力してください(ローマ字):",i+1);
	  fgets(search_name,64,stdin);                /* 検索する名前の読み込み */
	  printf("\n");
	  search_name[strlen(search_name)-1]=' ';     /* 改行を空白に変換 */

	  compare_char = strlen(search_name);         /* 比較する文字数(空白を含む) */

	  /*---- ファイルのオープン ---- */

	  if((read_list = fopen("address.txt","r"))==NULL){
	    printf("ファイルが開けません!!! \n");
	    return 1;
	  }

	  /*---- データの読み込みと比較、表示 --- */

	  for(i=0;i<=9;i++){

	    fgets(r_shimei[i],64,read_list);          /* 氏名の読み込み(改行付) */
	    r_shimei[i][strlen(r_shimei[i])-1]=' ';   /* 改行を空白に変換 */

	    fgets(r_tel[i],16,read_list);             /* 電話番号の読み込み(改行付) */
	    r_tel[i][strlen(r_tel[i])-1]=' ';         /* 改行を空白に変換 */

	    if(strncmp(r_shimei[i],search_name,compare_char)==0){
	      printf("\t\t氏名:%s\t電話番号:%s\n",r_shimei[i], r_tel[i]);
	    }
	  }

	  printf("\n");
	  fclose(read_list);                           /* ファイルのクローズ */
	  return 0;  
	}

3.3 プログラム解説

fgets(search_name,64,stdin);
キーボード(stdin)から1行の文字列を読み 込んで、それを配列(search_name)に格納している。最大読み込みバイ ト数は64バイトである。読み込まれた最後の文字は、改行 (\n)となる
search_name[strlen(search_name)-1]=' ';
改行を含んだ文字列の文字数は、関数 strlenでカウントしている。この文字数から1を引いた値が、改行があ る添え字を示すことになるので、その場所を空白に置き換えている。
compare_char = strlen(search_name);
比較すべき空白を含んだ文字数をカ ウントして、compare_charに格納している。
strncmp(r_shimei[i],search_name,compare_char)
文字列を比較する関 数で、等しければ0を返す。比較する文字列は、配列r_shimei[i]search_nameの先頭のcompare_charで示された数である。



ホームページ: Yamamoto's laboratory
著者: 山本昌志
Yamamoto Masashi
平成17年1月15日


no counter