- 締切済み
C言語の課題でまたまた悩んでいます。
前にも、投稿して一部はうまくいきその後自力で何とかしようと頑張ったのですがやはりできませんでした。そこでもう一度皆さんの力を借りたいと思い投稿しました。 改めまして、 課題は構造体で顧客情報を確保(キーボードで1~50の顧客情報の数を入力)し、分岐点(登録、一覧表示、削除、ファイル出力、終了)に行き、それぞれを行なうプログラムです。 登録では、名前、ふりがな、電話番号を入力(idは1から順につける)。名前、ふりがなの型はcharで確保して入力もそのままなんですが、電話番号の型はcharにして0~9までとハイフンのみ入力可能にし、他の文字を入力したらエラーを返すようにするみたいなんですが方法がわからないです。 一覧表示では、id、名前、ふりがな、電話番号をそれぞれ表示します。今のところ問題はないです。 削除では、指定したidを削除し、削除したidは再利用はできないがその分新たなidで顧客情報を入力することができる。 記述してエラーは出なかったのですが削除はされません。 ファイル出力では、csv形式で出力するみたいなんですが。記述してもエラーが返ってくるばかりでよくわからないです。構造体の出力の場合 、記述の仕方が違うと思うのですが???の部分など全体的に記述の仕方がわかりません。 ちなみに、私が記述したのは下記のとおりです。 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <conio.h> #include "top.h" #include "ichiran.h" #define size_id (4) #define size_name (24) #define size_huri (24) #define size_tel (16) struct kokyaku { long id[size_id]; char name[size_name]; char huri[size_huri]; char tel[size_tel]; struct kokyaku *next; }; int main() { int kokyaku , bunki , sakuzyo , i , j; //顧客情報確保の件数 メニュー画面での分岐 削除id番号 顧客情報の件数と比較 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)); } i = 0; while(bunki = 5){ printf("%s", top1); printf("処理区分>"); scanf("%d",&bunki); system("cls"); switch(bunki) //メニュー画面での分岐 { case 1: //登録 if(id <= kokyaku) { printf("***** 顧客登録画面 *****\n"); *(kok[i].id) = id; printf("氏名 :"); scanf("%s", kok[i].name); printf("ふりがな:"); scanf("%s", kok[i].huri); printf("電話番号:"); scanf("%s", kok[i].tel); id++; kok[i].next = &kok[i+1]; i++; }else{ printf("登録がいっぱいになりました"); } break; case 2: //一覧表示 printf("%s\n", ichiran1); printf("%s\n", ichiran2); j = i; i = 0; while(i < j) { printf("%d%5s%25s%25s\n", *(kok[i].id) , kok[i].name , kok[i].huri , kok[i].tel); i++; } printf("%s\n", ichiran2); break; case 3: //削除 scanf("%d",&sakuzyo); for(i = 0;i < kokyaku || i < sakuzyo;i++) { if(i == sakuzyo - 1) { kok[i-1].next = &kok[i+1]; } } kokyaku++; break; case 4: //ファイル出力 FILE *fp; if((fp = fopen("kokyaku.csv", "w")) == NULL ) { return 0; } while(fgets(???) != NULL) { printf("%s", ???); } fclose(fp); printf("プログラムが終了しました。\n"); return 0; break; case 5: //終了 return 0; break; default: //エラー printf("<<処理区分エラー>>"); break; return 0; } } return 0; } ちなみにエラーが出ている場所は削除とファイル出力の部分のみです。 完成にはまだ遠くおかしなところがたくさんあると思います。ご指摘よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- yama5140
- ベストアンサー率54% (136/250)
>課題は、構造体で顧客情報を確保(・略・)し、 >分岐点(登録、一覧表示、削除、ファイル出力、終了) >に行き、それぞれを行なうプログラムです。 ★5つのしたいことが、ランダムに発生するかのように設計されていますが・・?。 (プログラミングの勉強だからといっても、あまりにも非現実的では・・) ・5つの行程を直列に進めるような流れにすればいいのでは。 ◆登録が終わったら、 ◆一覧表示して、 ◆不要なものを削除して、 ◆ファイル出力・終了 (それぞれ関数にしたほうが視認性がいい) 「登録がいっぱいになりました」とメッセージを出しながら、 「ファイル出力」せずに「終了」《できてしまう》プログラムは、・・?。 >完成にはまだ遠くおかしなところがたくさんあると思います。 ★「課題」の目的は、《線形リストの理解》なのかなぁ? (ちょこっとしか表れないが・・) 「線形リスト」を使わずに「配列」を用い、例えば「削除」なら 「顧客番号」に負の数を入れるとかで区別できるし・・?。 ☆「課題」の真意をよく考えて、かつ、設計を見直されたら如何でしょう。 ☆シンプルが一番!
- stingy
- ベストアンサー率37% (144/379)
部分的にですが、 nextを使用する意味は理解されていますか? 誰の発想なんでしょう? 削除時に、 kok[i-1].next = &kok[i+1]; とされていますが、この後、kok[i]の再利用はどうするつもりでしょう? ここでforを抜けたとき、iの値は入力済み顧客数とは異なりますよね? 次の登録時、iの値がそのまま(多分sakuzyoかkokyaku)で処理を進めて大丈夫ですか? 登録・削除を繰り返していくと i==id-1 ではなくなってくるのは解ります? id <= kokyaku での判断もまずいし。 一覧表示で、 nextを使用しないと削除の時のコードが意味をなしませんよね? 削除する際は i == sakuzyo - 1 ではなく、 kok[i].id==id で判断、 削除した際のkok[i]はkok[???].nextにして流用。kok[i].nextもそれなりに書き換え。 kok[i].idは最初に0で初期化しておきましょう。 最後に登録したkok[]とid値、実際に入力した顧客数は別途変数を作って管理したほうが良いでしょう。 他にも色々ありますが、とりあえず。 それと、前回の質問へのリンクを張ったほうが良いと思いますよ。
- Werner
- ベストアンサー率53% (395/735)
とりあえず気付いた点だけ列挙します。 > long id[size_id]; 配列にする意味が分からない。 > struct kokyaku *next; 連結リストにするつもりでもなさそうだし何のために用意しているのか分からない。 > printf("顧客情報がありません。何件分確保しますか?(1 - 50)"); > scanf("%d",&kokyaku); 最大件数を保持する変数名が kokyaku なのは分かりにくい。 他の変数名も分かりやすいとは言い難いものがある。(ローマ字であることを差し引いて考えても) > while(bunki = 5) whileループの継続条件部で代入を行うのは気持ち悪い。 > case 2: //一覧表示 > j = i; ここでいきなりiを使う理由が分からない。 iに何か意味があるなら、こんな意味不明の変数名にしてはいけない。 > kok[i-1].next = &kok[i+1]; なぜこれで削除されたことになると思ったのですか? nextを参照している箇所はどこにもないので nextは(少なくともそのコードでは)無意味な情報です。 > while(fgets(???) != NULL) fgetsはファイルから読み込むための関数です。 ファイル出力したいなら書き出すための関数を使ってください。 fprintfならprintfと使い方はほとんど同じです。 > 記述してエラーは出なかったのですが削除はされません。 > ちなみにエラーが出ている場所は削除とファイル出力の部分のみです。 削除でエラーは出るのか出ないのか。 削除はどうやって実現するつもりですか?