• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:課題ができず困っています。)

課題ができず困っています。質問内容のポイントを教えてください。

このQ&Aのポイント
  • 課題は構造体で顧客情報を確保し、分岐点ごとに登録、一覧表示、削除、ファイル出力のプログラムを行います。
  • 登録では、名前、ふりがな、電話番号を入力します。電話番号は一定の条件で入力される必要があります。
  • 一覧表示では、登録された顧客情報を表示しますが、現在は表示が正しく行われていません。

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

> こんな感じになっています。良いのかはわかりませんが^^; > エラーは消えましたが、ファイル出力や削除もわからないんですけど、特に一覧表示がうまくいきません。 まあ細かいこというときりがないので、とりあえずは良しとしましょう。 で、ファイル出力と削除も後回しにするとして、 > 登録でidの1にnameにabc、huriにdef、telに1234-5678といれると > > 4399008abcdef1234-5678 んー、 struct kokyaku の定義は今はどうなってますか? そして出力している行はどんな感じですか? idはとりあえずおいといて、name hrui tel がくっついて出てしまっているのは %s%s%s のようにしているからでしょう。 > 1****abc*********************def*********************1234-5678******* > *はスペースのことです。 > と表示したいのです printf の書式指定のところを調べてみてください。 こんな感じにすると、全体で何桁分か確保した上で変数の変換結果が足りないときに 適当に埋めてくれます。 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { const char* str = "hello"; printf("<<%s>>\n"); printf("<<%10s>>\n"); printf("<<%-10s>>\n"); return 0; } 出力結果: <<hello>> << hello>> <<hello >> ファイル出力と削除がわからないということですけど、 ファイル出力の方は具体的に何がわかりませんか? ファイルをオープンするのと、書き込みの手順はわかりますよね? >記述してもエラーが返ってくるばかりでよくわからないです。 どんな書き方をして、どんなエラーになりましたか? 削除の方は、何らかの方法で「削除しました」って目印を つけるようにすればよいです。 とりあえず自分でもどういう「目印」にすればいいか考えてみてください。 あ、まずは一覧表示を正しくできるようにするのを優先で。

asthefancy
質問者

お礼

お礼遅くなりました。 一覧表示はスペースが空けられるようになりました。 しかし、idの代入がうまくいかなく意味のわからない数字が表示されたままです。 ファイル出力と削除のほうはもうちょっとがんばってみます。

asthefancy
質問者

補足

度々、すいません。 プログラムをいじっていてidがでてきたのでお知らせしました。 いままで、代入がうまくいってないとばかり思っていたのですが、もしかしたら表示の時うまくいってないのかと思い、いままでkok[i].idを表示としていたのですが、*(kok[i].id)を表示としたところうまくいきました。ありがとうございました。 まだ、削除や出力がうまくいってませんがもうすこしヒントを参考にがんばろうと思います。また質問することがあると思いますが、この質問も長くなりましたのでそのときは改めて投稿することにします。 そのときは改めてよろしくお願いします。 そして、ここまでありがとうございました。

その他の回答 (2)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

> memsetがまだよく理解できないです。 > もう少し頭が良くなりたいです。 難しく考えすぎじゃないですか? memsetがやっていることは、 memset(kok, '\0', sizeof(kok)); _______↑ このアドレスから sizeof (kok) だけ '\0' で埋める ってことです。 そんだけ。 質問にあるやりかただと +---+ |k |→ "七氏権兵衛" |o |→ "ななしのごんべえ" |k |→ "000-1234-5678" +---+ こんなのが、kok[0] とか kok[1] になるわけです。 で、よーく質問にあるプログラムを見直してみると、 > kok = (struct kokyaku *)malloc( sizeof(struct kokyaku) * (a)); これで、kokyaku の領域を人数分確保してます。これはいいですね。 で、構造体のメンバーもポインタで確保することにしていたので kok[i].id = (long*)malloc(size_id); kok[i].name = (char*)malloc(size_name); kok[i].huri = (char*)malloc(size_huri); kok[i].tel = (char*)malloc(size_tel); としてそれぞれの分を確保している。これもいいです。 じゃあなにが問題かというと memset(kok, '\0', sizeof(kok)); これ。 最初に書いたとおり、これは kok を先頭としてゼロを埋めていくわけですけど その先頭はなにを指しているかというと、 > kok = (struct kokyaku *)malloc( sizeof(struct kokyaku) * (a)); これですよね。 たぶん、一人分の領域を確保してそれを初期化したかったのだと思いますが、 それをするなら kok[i].id = (long*)malloc(size_id); こっちでmalloc したほうです。 結局 +---+ |k |→ "七氏権兵衛" |o |→ "ななしのごんべえ" |k |→ "000-1234-5678" +---+ この箱の中身をゼロ埋めしちゃったわけです。 つまり、せっかく確保した名前とかを格納する領域を 指していたところをパーにしちゃったと。 そこをアクセスしたので異常終了したというわけです。 んー削除やら出力の説明を書くスペースがないなw

asthefancy
質問者

お礼

またまたご指摘ありがとうございます。 いまは int main() { int kokyaku , bunki , i , j; //顧客情報確保の件数 メニュー画面での分岐 顧客情報の件数と比較 long id = 1; //顧客番号 struct kokyaku *kok; printf("顧客情報がありません。何件分確保しますか?(1 - 50)"); scanf("%d",&kokyaku); system("cls"); if(kokyaku < 1 || kokyaku > 50) { printf("<<入力範囲にありません>>\n"); printf("<<処理を中断します>>\n"); return 0; }else{ kok = (struct kokyaku *)malloc( sizeof(struct kokyaku) * (kokyaku)); } こんな感じになっています。良いのかはわかりませんが^^; エラーは消えましたが、ファイル出力や削除もわからないんですけど、特に一覧表示がうまくいきません。 登録でidの1にnameにabc、huriにdef、telに1234-5678といれると 4399008abcdef1234-5678 と表示されてしまいます。理想では、 1****abc*********************def*********************1234-5678******* *はスペースのことです。 と表示したいのです。 idは、1でも2でも4399008とわけのわからないすうじになってしまいます。うまく代入できずに、そのままの中身が出てるのでしょうが原因がよくわからないです。それと、理想のようにスペースをそれぞれの変数のサイズの分確保したいのですがどうすれば。。。 何度も質問してしまって申し訳ないです。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

a, b, c なんて一文字の名前の変数を使わない。 きちんと何に使う変数なのか意味がわかる名前をつける ただし、for ループでつかう i, j, k 辺りは例外。 kok[i].id = (long*)malloc(size_id); kok[i].name = (char*)malloc(size_name); kok[i].huri = (char*)malloc(size_huri); kok[i].tel = (char*)malloc(size_tel); memset(kok, '\0', sizeof(kok)); } 最後の memset で '\0'が埋められているのは一体どこなのか よーーく考えてみてください。 つか、前回のアドバイスにあった通りに 構造体の中で固定長の配列でとるようにすればいいのに。 printf("顧客情報がありません。何件分確保しますか?(1 - 50)"); scanf("%d",&a); kok = (struct kokyaku *)malloc( sizeof(struct kokyaku) * (a)); system("cls"); if(a < 1 || a > 50) もし、件数の入力でとんでもない値(十億件とか)が 入力されたらどうなるでしょう?

asthefancy
質問者

お礼

ご指摘ありがとうございます。 固定長で配列を確保しました。変数名も変えました。 >もし、件数の入力でとんでもない値(十億件とか)が >入力されたらどうなるでしょう? すごくめんどくさいことになるところでしたね^^; 顧客の数を確認した後に kok = (struct kokyaku *)malloc( sizeof(struct kokyaku) * (a)); を書くようにしました。 memsetがまだよく理解できないです。 もう少し頭が良くなりたいです。