連結リストに住所を格納し、それを検索するプログラムを作ってます

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
EUREKA

連結リストに住所を格納し、それを検索するプログラムを作ってます

#1

投稿記事 by EUREKA » 1年前

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

#define ZIP 8
#define ADDR 150
#define YOMI 64

struct address {

char zip[ZIP]; //郵便番号
char addr[ADDR]; //住所
char yomi1[YOMI]; //都道府県名の読み(ローマ字)
char yomi2[YOMI]; //市区町村名の読み(ローマ字)
char yomi3[YOMI]; //町域名の読み(ローマ字)

char *value;
struct address *next;
};

void read_address(struct address *p){

lib_scanf("%s",&p->zip);
lib_scanf("%s",&p->addr);
lib_scanf("%s",&p->yomi1);
lib_scanf("%s",&p->yomi2);
lib_scanf("%s",&p->yomi3);
struct address *next;
}

struct address gFront = {"","","","","",NULL};

void printList(void){
struct address *p;

/*セルを1ずつ辿りながらそのセルの内容を表示する*/
printf("LIST[ ");

/*通常,ダミーセルは連結リストの一部には含めません.
*ダミーセルの次のセルが連結リストの先頭になります.*/

p = gFront.next;
while (p != NULL){
printf("%s ",p->zip);
printf("%s ",p->addr);
printf("%s ",p->yomi1);
printf("%s ",p->yomi2);
printf("%s\n",p->yomi3);
p=p->next;
}
printf("]\n");
}

void insert(struct address *pre,struct address *new){

new->next = pre->next;
pre->next = new;
}

void searchList(char b){
int cnt = 0;
struct address *p;

p = gFront.next;
while (p != NULL){
if(p->zip == &b){
printf("%s ",p->zip);
printf("%s\n",p->addr);
cnt++;
}
p=p->next;
}
printf("%d件見つかりました\n",cnt);
}

int main(int argc,char *argv[]){

int a,i;
char b;
struct address *p;
struct address *tail;
tail = &gFront;

lib_open(argv[1]);
lib_scanf("%d",&a);

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

p = malloc(sizeof(struct address));
if (p== NULL){
fprintf(stderr,"エラー:malloc失敗\n");
exit(1);
}

if(gFront.next == NULL) tail = &gFront;

insert(tail,p);
tail = p;
if(i==a) break;
read_address(p);
}

printf("検索する文字列> ");
scanf("%s",&b);

while(strcmp(&b,"0") != 0){

searchList(b);

printf("検索する文字列> ");
scanf("%s",&b);
}

printf("プログラムを終了します\n");

return 0;
}

コンパイル
gcc main.c lib.c -o main.exe

現在の実行結果
検索する文字列>0600806
0件見つかりました

検索する文字列>0
プログラムを終了します


理想の実行結果
./main.exe address.txt
検索する文字列>0600806
0600806 北海道札幌市北区北六条西
1件見つかりました

検索する文字列>0
プログラムを終了します

address.txt
0600806 北海道札幌市北区北六条西 hokkaido sapporoshikitaku kita6-jonishi
0040021 北海道札幌市厚別区青葉町 hokkaido sapporoshiatsubetsuku aobacho
1000011 東京都千代田区内幸町 tokyoto chiyodaku uchisaiwaicho

main関数のfor文で読み込んだ住所を連結リストに格納しています。
lib_open関数は、住所ファイルを読み込むための初期化を行う関数で
lib_scanf関数は、住所ファイルを読み込む関数です

自分で原因を考えてみたのですが
上の実行結果を例にするとどうやらinsert関数で引数として入力した0600806が
文字化けして0▒という文字列になっています。
そのため、0600806と入力しても検索結果が0件になってしまっているようです。
どうすればこの文字化けを防ぎ、入力した文字列をそのまま読み込むようになるのでしょうか。
読みにくいプログラムで申しわけありません。

参照魚
記事: 109
登録日時: 6年前

Re: 連結リストに住所を格納し、それを検索するプログラムを作ってます

#2

投稿記事 by 参照魚 » 1年前

lib_scanf関数を独自に定義されているので何とも回答のしようがありませんが、
scanfと同等だと仮定した場合、第2引数に&がついているためかと思います。

コード:

void read_address(struct address *p){
	// &p->xxx ではなく p->xxx
	lib_scanf("%s",&p->zip);
	lib_scanf("%s",&p->addr);
	lib_scanf("%s",&p->yomi1);
	lib_scanf("%s",&p->yomi2);
	lib_scanf("%s",&p->yomi3);
	struct address *next;
}

EUREKA

Re: 連結リストに住所を格納し、それを検索するプログラムを作ってます

#3

投稿記事 by EUREKA » 1年前

回答ありがとうございます!
lib_scanfはscanfと同等です。説明不足で申し訳ありません。
&を消して実行してみたのですが、実行結果は変わりませんでした。
連結リストに住所ファイルを格納することには成功しています。search関数に思い通りの実行結果にならない原因など無いでしょうか

box
記事: 2002
登録日時: 13年前

Re: 連結リストに住所を格納し、それを検索するプログラムを作ってます

#4

投稿記事 by box » 1年前

理想の実行結果
./main.exe address.txt
検索する文字列>0600806
0600806 北海道札幌市北区北六条西
検索する文字列の例として0600806をあげていますね。

コード:

char b;
なんで定義が1文字だけなんですか?

コード:

printf("検索する文字列> ");
scanf("%s",&b);
bは1文字分しかないのになんで入力指定文字列が%sなんですか?

コード:

if(p->zip == &b){
何をしようとしているんですか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 13年前

Re: 連結リストに住所を格納し、それを検索するプログラムを作ってます

#5

投稿記事 by box » 1年前

そもそもの仕様として、検索する文字列は
郵便番号の「先頭文字だけ」でいいんですか?
char b;
の定義から、そう読めます。
もしそうだとすると
「理想の実行結果」にあがっている「郵便番号全体」の話と
食い違ってますよ。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 13年前

Re: 連結リストに住所を格納し、それを検索するプログラムを作ってます

#6

投稿記事 by box » 1年前

構造体のメンバーに謎の
char *value;
っていうのがあります。これの役目は?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

返信

“C言語何でも質問掲示板” へ戻る