セグメンテーションエラーで困っています

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

セグメンテーションエラーで困っています

#1

投稿記事 by SILVER » 13年前

疑似的なATMを作る宿題なのですが、振込をするときに間違った振込先を入力するとセグメンテーションエラーになってしまいます。デバッガもやってみましたが間違いがわからないので質問させていただきます。

#include<stdio.h>
#define TEXT 32
#define BUFFER_SIZE 512

struct account{
char name[TEXT];/*預金者名前*/
int num;/*口座番号*/
int money;/*預金額*/
int code;/*暗証番号*/
};
struct account *search_account(struct account*,int);
void print_account(struct account *);
int transfer(struct account *,struct account*,int);
int accountcode(int);
int main(void)
{
char buf[TEXT];
int action,acnum,PIN,judge,decrement,number,ans;/*暗証番号 太郎2345 花子5678 一郎0123*/
struct account Data[BUFFER_SIZE]={{"立命太郎",1234,1234560,accountcode(Data[0].num)},{"野路花子",5678,987600,accountcode(Data[1].num)},{"草津一郎",9012,538600,accountcode(Data[2].num)}};
struct account *point;
point=&Data[0];/*先頭アドレスを格納*/
for(;;){
printf("[0]終了 [1]残高表示 [2]お引出し[3]お振込:");
fgets(buf,TEXT,stdin);
action=atoi(buf);
/*////////////////////終了//////////////////////*/
if(action==0)
{
break;
}
/*/////////////////////////////////////////////*/
printf("口座番号を入力して下さい:");
fgets(buf,TEXT,stdin);/*口座番号入力*/
acnum=atoi(buf);

printf("暗証番号を入力して下さい:");
fgets(buf,TEXT,stdin);
PIN=atoi(buf);
/*//////////////////残金表示///////////////////*/

if(action==1)
{
if(search_account(point,acnum)==NULL)
{
printf("口座番号を確認して下さい\n");
}
else if(search_account(point,acnum)->code!=PIN)
{
printf("暗証番号を確認してください\n");
}
else
{
printf("残高は %d円です\n",search_account(point,acnum)->money);/**/
}
}
/*/////////////////ひきだし///////////////////*/
else if(action==2)
{
if(search_account(point,acnum)==NULL)
{
printf("口座番号を確認して下さい");
}
else if(search_account(point,acnum)->code!=PIN)
{
printf("暗証番号を確認してください");
}
else
{
printf("引出し額を入力して下さい:");
fgets(buf,TEXT,stdin);
decrement=atoi(buf);
if(search_account(point,acnum)->money<decrement)
{
printf("預金額が不足しています\n");
}
else
{
search_account(point,acnum)->money-=decrement;
printf("ありがとうございました.残金は%d円です\n",search_account(point,acnum)->money);
}
}
}
/*////////////////振込/////////////////////////*/
else if(action==3)
{
if(search_account(point,acnum)==NULL)
{
printf("口座番号を確認して下さい\n");
}
else if(search_account(point,acnum)->code!=PIN)
{
printf("暗証番号を確認してください\n");
}
else
{
printf("振込先の口座番号を入力して下さい");
fgets(buf,TEXT,stdin);
number=atoi(buf);

if((search_account(point,number)->num)==number)
{
printf("振り込み額を入力して下さい;");
fgets(buf,TEXT,stdin);
decrement=atoi(buf);

ans=transfer(search_account(point,acnum),search_account(point,number),decrement);

if(ans==-1)
{
printf("残高が不足しています\n");
}
else if(ans==1)
{
printf("%s様に%d円振込みました\nありがとうございました.残金は%d円です\n",search_account(point,number)->name,decrement, search_account(point,acnum)->money);
}
}
else
{
printf("振込先に間違いがあります\n");
}
}
}
}

printf("ご利用ありがとうございました\n");
}

/*暗証番号算出*/
int accountcode(int num)
{
return (num+1111)%10000;
}

struct account *search_account(struct account *whole,int id)
{
if(whole->num!=id)
{
search_account(whole+1,id);
}
else if(whole->num==id)
{
return whole;/*そこからの個人データ全体を返す*/
}
}
/*振込を行う関数 成功なら1,失敗なら-1を返す*/
int transfer(struct account *from,struct account *to,int amount)
{
if((from->money)<amount)
{
return -1;
}
else
{
(from->money)-=amount;
(to->money)+=amount;
return 1;
}

}

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: セグメンテーションエラーで困っています

#2

投稿記事 by h2so5 » 13年前

存在しない振込先を指定した場合、search_account関数がどのような動きをするか考えてみてください。

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

Re: セグメンテーションエラーで困っています

#3

投稿記事 by box » 13年前

search_account関数の戻り値をNULLと比較している局面がいくつかあるのに対し、
search_account関数からNULLを返そうとしているコードが見当たらないような気がします。

全部探したけど見つからなかった、という場合にNULLをreturnする必要があるのではないでしょうか。

今のコードでは、預金者情報を再帰的にすべてサーチした後も、
預金者情報以外のエリア(つまり、サーチしてはいけないエリア)を
ずっとサーチしに行こうとしているように見えます。私の見間違いであればいいのですけれど。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

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

Re: セグメンテーションエラーで困っています

#4

投稿記事 by box » 13年前

ていうか、search_account関数を再帰呼び出しの形にしていることで
話がややこしくなっているようにも思えます。
引数に「何人分の預金者情報があるか(今回は3人分)」あたりを加えて、
その人数分だけふつうにfor文か何かでループすれば事足りるような気がします。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

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