• 締切済み

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; } ちなみにエラーが出ている場所は削除とファイル出力の部分のみです。 完成にはまだ遠くおかしなところがたくさんあると思います。ご指摘よろしくお願いします。

みんなの回答

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.3

>課題は、構造体で顧客情報を確保(・略・)し、 >分岐点(登録、一覧表示、削除、ファイル出力、終了) >に行き、それぞれを行なうプログラムです。 ★5つのしたいことが、ランダムに発生するかのように設計されていますが・・?。 (プログラミングの勉強だからといっても、あまりにも非現実的では・・) ・5つの行程を直列に進めるような流れにすればいいのでは。 ◆登録が終わったら、 ◆一覧表示して、 ◆不要なものを削除して、 ◆ファイル出力・終了 (それぞれ関数にしたほうが視認性がいい)  「登録がいっぱいになりました」とメッセージを出しながら、  「ファイル出力」せずに「終了」《できてしまう》プログラムは、・・?。   >完成にはまだ遠くおかしなところがたくさんあると思います。 ★「課題」の目的は、《線形リストの理解》なのかなぁ?  (ちょこっとしか表れないが・・)  「線形リスト」を使わずに「配列」を用い、例えば「削除」なら  「顧客番号」に負の数を入れるとかで区別できるし・・?。 ☆「課題」の真意をよく考えて、かつ、設計を見直されたら如何でしょう。 ☆シンプルが一番!

  • stingy
  • ベストアンサー率37% (144/379)
回答No.2

部分的にですが、 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)
回答No.1

とりあえず気付いた点だけ列挙します。 > 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と使い方はほとんど同じです。 > 記述してエラーは出なかったのですが削除はされません。 > ちなみにエラーが出ている場所は削除とファイル出力の部分のみです。 削除でエラーは出るのか出ないのか。 削除はどうやって実現するつもりですか?

関連するQ&A

  • 課題ができず困っています。

    前回は部分的に質問を投稿したのですが、あまりにもわからないのでもう少し範囲を広げて投稿することにしました。よろしくお願いします。 課題は構造体で顧客情報を確保(顧客情報入力の前に、キーボードで1~50の顧客情報の数を入力し、その数の構造体を確保)し、分岐点(登録、一覧表示、削除、ファイル出力、終了)に行き、それぞれを行なうプログラムです。 登録では、名前、ふりがな、電話番号を入力(idは1から順につける)。名前、ふりがなの型はcharで確保して入力もそのままなんですが、電話番号の型はcharにして0~9までとハイフンのみ入力可能にし、他の文字を入力したらエラーを返すようにするみたいなんですが方法がわからないです。それと現段階ではビルドはうまくいくのですが、登録画面に行くとidをいれるところ(多分)で論理エラーが起きてexeが強制終了してしまいます。 ちなみに、それぞれの出力サイズはidが5、名前が24、ふりがなが24、電話番号が16です。 一覧表示では、id、名前、ふりがな、電話番号を改行なしで位置はidは左から1番目、名前は6番目、ふりがなは32番目、電話番号が57番目からそれぞれ表示します。 今記述している段階ではスペースがあくことなくすべて左詰で表示され、顧客番号が変な数字になってしまいます。 削除では、指定した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 (5) #define size_name (24) #define size_huri (24) #define size_tel (16) struct kokyaku { long *id; char *name; char *huri; char *tel; }; int main() { int a , b , i , j; //顧客情報確保の件数 メニュー画面での分岐 顧客情報の件数と比較 long c = 1; //顧客番号 struct kokyaku *kok; printf("顧客情報がありません。何件分確保しますか?(1 - 50)"); scanf("%d",&a); kok = (struct kokyaku *)malloc( sizeof(struct kokyaku) * (a)); system("cls"); if(a < 1 || a > 50) { printf("<<入力範囲にありません>>\n"); printf("<<処理を中断します>>\n"); return 0; }else{ for(i = 0;i < a;i++){ 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)); } } i = 0; while(b = 5){ printf("%s", top1); printf("処理区分>"); scanf("%d",&b); system("cls"); switch(b) //メニュー画面での分岐 { case 1: //登録 if(c <= a) { printf("***** 顧客登録画面 *****\n"); *(kok[i].id) = c; printf("氏名  :"); scanf("%s", kok[i].name); printf("ふりがな:"); scanf("%s", kok[i].huri); printf("電話番号:"); scanf("%s", kok[i].tel); c++; i++; } else { printf("登録がいっぱいになりました"); } break; case 2: //一覧表示 printf("%s\n", ichiran1); printf("%s\n", ichiran2); j = i; i = 0; while(i < j) { printf("%d%s%s%s\n", kok[i].id , kok[i].name , kok[i].huri , kok[i].tel); i++; } printf("%s\n", ichiran2); break; case 3:    //削除 break; case 4:    //ファイル出力 break; case 5:     //終了 break; default: //エラー printf("<<処理区分エラー>>"); break; return 0; } } return 0; } おかしなところがたくさんあるとおもいますが、ご指摘よろしくお願いします。

  • C言語の構造体で悩んでます。

    構造体で顧客情報を管理する課題に取り組んでいるんですが、言語は苦手な分野で解決しかねてます。みなさんの力を借りたいです。お願いします。 課題は、構造体で顧客情報を確保(顧客情報入力の前に、キーボードで1~50の顧客情報の数を入力し、その数の構造体を確保)し、その後、顧客情報を登録するというものです。 私が記述したのは下記のとおりです。 間違いだらけだと思います。すみません。 #define size_id (5) #define size_name (25) #define size_huri (25) #define size_tel (17) struct kokyaku { long *id; char *name; char *huri; char *tel; }; int main() { int a , i; // 構造体確保の数、構造体参照時使用 long c = 1; // id struct kokyaku *ko; printf("顧客情報がありません。何件分確保しますか?(1 - 50)"); scanf("%d",&a); ko = (struct kokyaku *)malloc( sizeof(struct kokyaku) * (a)); if(a >= 1 || a <= 50) { for(i = 0;i < a;i++){   ko[i].id = (long*)malloc(size_id);   ko[i].name = (char*)malloc(size_name);   ko[i].huri = (char*)malloc(size_huri);   ko[i].tel = (char*)malloc(size_tel);       } }else{ printf("<<入力範囲にありません>>\n"); printf("<<処理を中断します>>\n"); return 0; } while(c <= a) {  i = 0;  printf("***** 顧客登録画面 *****\n");  ko[i].id = &c;  printf("氏名  :");  scanf("%s", ko[i].name);  printf("ふりがな:");  scanf("%s", ko[i].huri);  printf("電話番号:");  scanf("%s", ko[i].tel);  c++;  i++; } } エラーとか特にないのですが、構造体を件数分確保できていないと思います。 この後にも削除やファイル出力といった展開をさせなければならないのですが、後はなんとか自力でがんばろうと思います。 乱文ですみません。 よろしくお願いします。

  • C言語 プログラミング

    C言語、プログラミングの質問です。 構造体について、 プログラムを組んでみたのですが、上手く出力されません。実行時にはエラーはないのですが、出力時に上手くいきません。どなたかどこがおかしいかわかる方、教えていただけませんでしょうか? #include <stdio.h> struct user{ char *name; char *id; int books; }; int main (void) { struct user u; printf("氏名を入力して下さい。"); scanf("%s",u.name); printf("パスワードを入力してください。"); scanf("%s",u.id); printf("年齢を入力してください。"); scanf("%d",&u.age); printf("氏名 %s\n",u.name); printf("パスワード %s\n",u.id); printf("年齢 %d\n",u.age); return 0; } よろしくお願いします。

  • C言語での構造体

    C言語の構造体で配列を扱うとき、 struct ○○{  char ○○[○] とすれば出来ますが、同じようにして構造体で二次元配列を扱うことは出来ますか? 一度組んでみたのですが、 #include<stdio.h> struct aaa{ int no; char name[128]; char y_name[128]; char n_name[128]; char s_name[128][128]; }; int main(void){ int i; struct aaa iryo[99]; printf("入力前\n"); /* 構造体配列に scanf()でデータを入力 */ for(i = 0; i < 3; i++) { // printf("input...\n"); scanf("%d", &iryo[i].no); scanf("%s", iryo[i].name); scanf("%s", iryo[i].y_name); scanf("%s", iryo[i].n_name); scanf("%s", iryo[i].s_name); } printf("入力後\n"); printf("出力前\n"); /* 入力データの確認 */ for(i = 0; i < 3; i++) { printf("番号:%02d 内容:%s Y分岐:%s N分岐:%s 他分岐:%s\n", iryo[i].no, iryo[i].name, iryo[i].y_name, iryo[i].n_name, iryo[i].s_name); } printf("出力後\n"); printf("%d",sizeof(struct aaa)); return 0; } としたら、エラーは出ませんが、実行すると何も表示されませんでした。

  • C言語エラー

    C言語をいじっているのですが、16行目と19行目の「型」の前に「;」がありませんと表示されます。 どこをどう改善すればいいか教えてもらえないでしょうか /*遊び半分*/ #include <stdio.h> #include <process.h> int main() { char dear; printf("ああああ\n"); printf("ああああ \n"); scanf_s("%c", &dear); switch (dear){ case 'A04': ; int main(void); { printf("ああああ\n"); int main(void); printf("あああ\n"); printf("あああ\n"); break; system("pause"); return 0; } case 'C34' : printf("\n"); break; case 'E24' : printf("\n"); break; case 'F38' : printf("\n"); break; default: printf("メッセージはありません\n"); break;} return 0;

  • C言語の課題で

    C言語の課題で 「成績集計プログラム 入力件数nをキーボードより入力し、n人分のテストデータを入力する。その際、合計点、最高点、最低点を求め、最後に平均点を計算しそれぞれを出力するプログラムを作成せよ。ただし、平均点は実数型とし小数点第2位まで出力する。平均点以外の変数は整数型とする。」というのが出ました。 #include <stdio.h> int main(void) { int n,a,b,c; int res,i; printf("入力件数を入力して下さい。\n"); scanf("%d",&n); for(i = 1; i <= n; i++) { printf("点数を入力して下さい。\n"); scanf("%d",&a); printf("%d人目=>%d\n",i,a); if(i == res) break; } return 0; } ここまでは、出来たのですが、後が分かりません。どなたか教えていただけませんか?お願いします。

  • C言語について プログラムが動きません

    ゲームのプログラムを作りたいものです。 今、試作の途中の段階で以下のようなプログラムを作ってみたのですが、 コアダンプが表示されてうまく起動しません。 どの点を変更すればいいのか、教えてください。 使っている言語はC言語です。 よろしくお願いいたします。 #include <stdio.h> #include <string.h> struct monster{ int type; /* タイプ */ char trick[25]; /* 技 */ char trick2[25]; /* 技2 */ int tricktype; /* 技1のタイプ */ int tricktype2; /* 技2のタイプ */ int trickeffect; /* 技1の威力 */ int trickeffect2; /* 技2の威力 */ char name[10]; /* 名前 */ int attack; /* 攻撃力 */ int diffence; /* 防御力 */ int speed; /* 素早さ */ /* 1,fire 2,water 3,nature 4,thunder 5,wind */ }; char names[5][10] = {"v", "w", "x", "y", "z"}; main(){ int s = 0; int a[3]; int i; int m; struct monster monster[5] = { { 1, "a", "b", 1, 2, 120, 80, "v", 60, 60, 60}, { 2, "a", "b", 2, 3, 120, 80, "w", 60, 60, 60}, { 3, "a", "b", 3, 4, 120, 80, "x", 60, 60, 60}, { 4, "a", "b", 4, 5, 120, 80, "y", 60, 60, 60}, { 5, "a", "b", 5, 1, 120, 80, "z", 60, 60, 60}, }; printf("好きなモンスターを3つ選んでください\n\n"); while (s < 1){ for (i = 0; i++; i<3){ printf("%d体目を選んでください。\n\n", i+1); for(m = 0; m++; m < 4) printf("%d, %s\n", m+1, monster[m].name); printf("5, %s\n\n", monster[4].name); scanf("%d", a[i]); printf("%d体目 : %s\n\n", i+1, monster[a[i]-1].name); } printf("これでよろしいですか?\n"); for(i = 0; i++; i<2) printf("%d体目 : %s ", i+1, monster[a[i]-1].name); printf("3体目 : %s\n\n", monster[a[2]-1].name); printf("1、はい 2、いいえ\n"); scanf("%d", &i); if(i=1) return s = 1; else return s = 0; } }

  • C言語について

    #include <stdio.h> struct syoukai{ int no; char name[5]; }; int main(void) { struct syoukai mine = {3, "aaaaa"}; int cmdID ; printf("コマンドを入力してください\n"); scanf("%d\n",cmdID); if(cmdID == 1) printf("%d\n",syoukai.no, syoukai.name); } これをコンパイルして実行すると Segmentation fault とエラーになってしまい原因がわかりません 教えていただけますか?

  • C言語

    はじめまして。 C言語を学習しております。 参考書の練習問題19(下記)で以下の部分がどうしても理解できません。 1、【(People*)mallock】の部分で、mallockの前のPeopleを()でくくる意味とPeopleの後に*を付ける意 味がわかりません。 2、InputPeople関数とShowPeople関数の最後の部分(●の印をしている部分)になぜretutn 0がいらないのでしょうか(原文にはretutn 0の記述がありません)。 3、【while (1)】の部分で、while文の使い方は、「while(条件式){ 繰り返す文;}」のはずですが、なぜ条件式の部分が1なのでしょうか(a > bなどの形ではないのでしょうか)。 4、【while (1)】の部分で、InputPeople関数の引数としてdata[count]がありますが、何を意味しているのかがわかりません。People型の変数dataとint型の変数countを組み合わせてどういう意味合いになるのでしょうか。dataとcountはどういう関係でしょうか。 5、【while (1)】の部分で、count++する意味がわかりません。 6、【while (1)】文内の下記の記述が何を意味しているのかがわかりません。       if (count >= datasize) {       datasize += 10;       data = (People*)realloc(data,sizeof(People) * datasize);      } ここでつまづいて先に進めず困っております。 どうか教えていただきたく、お願い致します。 ●練習問題19 練習問題16(一番下に参考として解答を載せています)の、 「3人分の、名前、年齢、性別、を入力して表示するプログラムを作りなさい。 ただし、データは構造体で記憶することとし、 また、データの入力と表示はそれぞれ専用の関数を作って行うこととする。」 という問題を元に、何人分でも入力できるように改造しなさい。 なお、年齢に-1が入力されれば入力終了とする。 ※配列番号がint型なのでint型の最大値まで扱えれば良い。 ●練習問題19の解答 #include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct { char name[256]; int age; int sex; } People; void InputPeople(People *data); void ShowPeople(People data); int main(void) { int i,count,datasize; People *data; datasize = 10; data = (People*)malloc(sizeof(People) * datasize); count = 0; while (1) { InputPeople(&data[count]); if (data[count].age == -1) break; count++; if (count >= datasize) { datasize += 10; data = (People*)realloc(data,sizeof(People) * datasize); } } for (i = 0;i < count;i++) { ShowPeople(data[i]); } free(data); return 0; } void InputPeople(People *data) { printf("名前:"); scanf("%s",data->name); printf("年齢:"); scanf("%d",&data->age); printf("性別(1-男性、2-女性):"); scanf("%d",&data->sex); printf("\n");     /*●retutn 0は不要?*/ } void ShowPeople(People data) { char sex[16]; printf("名前:%s\n",data.name); printf("年齢:%d\n",data.age); if (data.sex == 1) { strcpy(sex,"男性"); } else { strcpy(sex,"女性"); } printf("性別:%s\n",sex); printf("\n");     /*●retutn 0は不要?*/ } ●練習問題16の解答 #include <stdio.h> #include <string.h> typedef struct { char name[256]; int age; int sex; } People; void InputPeople(People *data); void ShowPeople(People data); int main(void) { People data[3]; int i; for (i = 0;i < 3;i++) { InputPeople(&data[i]); } for (i = 0;i < 3;i++) { ShowPeople(data[i]); } return 0; } void InputPeople(People *data) { printf("名前:"); scanf("%s",data->name); printf("年齢:"); scanf("%d",&data->age); printf("性別(1-男性、2-女性):"); scanf("%d",&data->sex); printf("\n"); } void ShowPeople(People data) { char sex[16]; printf("名前:%s\n",data.name); printf("年齢:%d\n",data.age); if (data.sex == 1) { strcpy(sex,"男性"); } else { strcpy(sex,"女性"); } printf("性別:%s\n",sex); printf("\n"); }

  • C言語の課題が分からなくて困っています。

    http://www.picamatic.com/view/5868047_かかか/ URLの画像のような数当てゲームのプログラムを作成しているのですが、(1)~(5)の部分が分からなくて困っています。 面倒だとは思いますが、教えていただけないでしょうか。 #include<stdio.h> #include<stdlib.h> #include<time.h> int mani(void){ int i,x,y; srand((unsigned int)time(NULL)); (1) //1~1000の数をランダムに作成   y=0; //入力回数yを0にセットする for(;;){ //break文があるまで以下の処理を繰り返す printf("1以上1000以下の整数を入力してください。\n"); (2) //答えの入力 y=y+1; //入力回数yを1を増やす (3) //あたりの場合 printf("%d回目で当たりました。\n",y); (4) } else{ //外れの場合    (5) printf("違います。もっと大きな数です。\n"); else printf("違います。もっと小さな数です。\n"); } } return 0; }

専門家に質問してみよう