• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C言語初心者の者です。)

C言語初心者の方の質問について

このQ&Aのポイント
  • C言語初心者の方が、構造体を使用した名簿の作成について質問しています。
  • 具体的には、(1)入力判定時に先頭が0入力の場合にエラーを返す方法と記述と、(2)一覧表示時の不正な文字入力によるエラーの原因を知りたいとのことです。
  • 解決策を提案する前に、他にも修正が必要な部分があるかを確認する必要があります。

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

せっかく fgets→ sscanf としているのだから ・fgetsの戻り値を確認。 行が長すぎて、読み込んだ配列の長さと同じになってないか、逆に読み込み失敗で0になってないかを確認する。 ・bufferの中身を確認。 期待している文字列になっているかを確認する。 例えば、人数を入力するところでは、最初に出てきた文字が0でない数字になっているか、数字がintで収まらないくらい連続していないか確認する。 とすればよいのでは? > {//**確保できた場合はメモリを動的に確保**// > kok = (Meibo *)malloc( sizeof(Meibo) * num); > if(kok==NULL) > { > stop_func(); > } > free(kok); > } これを含めてなのですが、コメントはわざとですか? C言語の従来型のコメントは /* から */までです。改行等も含めて */ が現れるまでがコメントの範囲で、入れ子不可です。逆に1行の途中の部分だけコメントアウトすることもできます printf( "%d", /* 1, */ 2 ) ; /* 2を出力する。 1はコメントアウトされている */ C++で // が追加になりました。これは //から行末までがコメントになります。後に、C言語でも // を行末までのコメントとして使えるようになりました。正し、古いコンパイラ等、対応していないものもあります。 これらを理解しているのならよいのですが、全部 //** **//になっているのを見ると、誤解している気がします。 さて、ここですが、 kokの領域を確保してすぐに解放しています。これでは、まったく意味がありません。 >case 1 ://**登録**// >n = add(data, n,*kok,num); >break; >case 2 : //**一覧**// >n = printall(data, n,*kok,num); >break; しかも、そのあとでkokが使われています。 free関数は、領域の解放はしますが、変数の初期化はしません。よって、この *kok は kokが指すMeibo型(しかし、その領域はすでにfreeで解放済み)ということになります。 現在はたまたま動作しているかもしれませんが、いつ不具合が起ってもおかしくない状態です。 > sscanf(t->from,"%s",&kok); このような行がいくつもありますが ・scanf系関数の"%s"に対応するのは、char *型です。 kokが引数で「Meibo kok」と宣言されているので、 &kokは「Meibo *型」です。scanfはこのような場合、「何もチェックせずchar *型だと勝手に思いこんで処理します」 ・しかも、kokは関数でのローカル変数ですから、returnした段階でメモリから無くなります。参照渡しをしたいのなら、ポインタと実体が逆です。(しかも、先に書いたように、呼び出しがわでは、解放済みの領域を使おうとしています) もう一度落ち着いて設計をやりなおしたほうがよいのではないでしょうか。

mew-ktrk
質問者

お礼

素早い回答有難うございます。 kmee様の助言お陰で、疑問点は無事に解決することが出来ました。 また、他の点もご指摘頂き有難うございます。 コメント行に関しましては、自分の勘違いが原因です。 Cを始めたての頃「//**~**//」でコメントアウトされているものを見て、 その記述が正しいものだと誤解していたようです。 疑問が解決でき、その他の部分も修正が出来たので本当に助かりました。 また何かありましたらご相談するかと思いますが、その時はまた宜しくお願い致します。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C言語について

    次のような問題です。 問 自然数nを入力し、nを3で割って割り切れるかどうかを判定し結果を表示する。「割り切れる」、「1余る」、「「2余る」のいずれかが入るものとする。 このようなものをつくりました。 #include<stdio.h> int main(void) { int n; printf("自然数:"); scanf("%d",&n); if(n==0){ printf("割り切れる\n"); }else if(n==1){ printf("1余る\n"); }else{ printf("2余る"); } return(0); } これで合っているかよろしくお願いします。

  • 代入されません(C言語)

    こんにちは。 早速質問させていただきます。 申し訳ありませんが、問題の概要など話し始めるととても時間がかかってしまう為省略させていただきます。 下記のプログラムなのですが(私はプロではないため醜いプログラムですがご了承ください)、 #include <stdio.h> int num[8][5] = {{0,0,0,0,0},{0,0,1,0,0},{0,1,0,0,0},{0,1,1,0,0}, {1,0,0,0,0},{1,0,1,0,1},{1,1,0,1,0},{1,1,1,0,0}}; int ic = 0; int i=0, j=0; int id=0;//IDナンバー int m0=0, m1=0, m2=0; //中間層 int z0=0, z1=0; int t0=0, t1=0; double s0=0,s1=0; //総和 double w00=0, w01=0, w02=0, w10=0, w11=0, w12=0;//重み double sikii0=1, sikii1=1; //しきい値(θ) θ0とθ1 int t; //正解 double hoge = 0.1; double mm0, mm1, mm2; //p2. 4)学習 で使用 //プロトタイプ宣言 void input(void); void tyukan(void); void souwa(void); //総和 void hantei(void); void seikai(void); void omomi1(void); void omomi2(void); main(){ while(ic<70){ if(id > 7){ id=0; i=0; j=0; } getchar(); printf("IC = %d ID = %d\n", ic, id); input(); tyukan(); souwa(); hantei(); seikai(); if(z0 != t0) omomi1(); else if(z1 != t1) omomi2(); i++; ic++; id++; } return 0; } void input(){ printf("入力データ M=%d A=%d B=%d\n", num[i][j], num[i][j+1], num[i][j+2]); } void tyukan(){ if(id == 0){ m0=0; m1=0; m2=0; mm0=0; mm1=0; mm2=0; s0=0; s1=0; } m0=num[i][0]+num[i][1]+num[i][2]; m1=num[i][0]+num[i][1]; m2=num[i][0]+num[i][2]; //中間層m0m1m2に代入 mm0 = (double)m0; mm1 = (double)m1; mm2 = (double)m2; printf("中間層 m0=%d m1=%d m2=%d \n", num[i][0]+num[i][1]+num[i][2], num[i][0]+num[i][1], num[i][0]+num[i][2]); } void souwa(void){ printf("総和 s0=%f s1=%f\n",(double)m0*w00 + (double)m1*w01 + (double)m1*w02, (double)m0*w10 + (double)m1*w11 + (double)m2*w12); } //*****関数判定***************************************** void hantei(void){ printf("判定は "); if(s0 >= sikii0){ printf("z0 = 1 "); z0=1; } else{ printf("z0 = 0 "); z0=0; } if(s1 >= sikii1){ printf("z1 = 1\n"); z1=1; } else{ printf("z1 = 0\n"); z0=0; printf("sikii1 %f\n",sikii1); printf("sikii0 %f\n",sikii0); } } void seikai(void){ printf("正解は "); printf("t0 = %d t1 = %d\n", num[id][3], num[id][4]); t0=num[id][3]; t1=num[id][4]; } void omomi1(void){ if(z0 == 0 && t0 == 1){ w00 = w00 + (hoge*mm0); w01 = w01 + (hoge*mm1); w02 = w02 + (hoge*mm2); sikii0 = sikii0-hoge; printf("重み変更 00 %f\n重み変更 01 %f\n重み変更 02 %f\n", w00, w01, w02); printf("閾値 %f\n", sikii0); } else if(z0 == 1 && t0 == 0){ w00 = w00 - (hoge*mm0); w01 = w01 - (hoge*mm1); w02 = w02 - (hoge*mm2); sikii0 = sikii0+hoge; printf("重み変更 00 %f\n重み変更 01 %f\n重み変更 02 %f\n", w00, w01, w02); printf("閾値 %f\n", sikii0); } } void omomi2(void){ if(z1 == 0 && t1 == 1){ w10 = w10 + (hoge*mm0); w11 = w11 + (hoge*mm1); w12 = w12 + (hoge*mm2); sikii1 = sikii1-hoge; printf("重み変更 10 %f\n重み変更 11 %f\n重み変更 12 %f\n", w10, w11, w12); printf("閾値 %f\n", sikii1); } else if(z1 == 1 && t1 == 0){ w10 = w10 - (hoge*mm0); w11 = w11 - (hoge*mm1); w12 = w12 - (hoge*mm2); sikii1 = sikii1+hoge; printf("重み変更 10 %f\n重み変更 11 %f\n重み変更 12 %f\n", w10, w11, w12); printf("閾値 %f\n", sikii1); } } 問題はこのプログラムがID7になった時に発生します。 関数hanteiの部分で s0 >= sikii0とs1 >= sikii1がそれぞれ真だったらz0(またはz1)に1を代入するように 作ったのですが、 IC=7 ID=7の部分では,s0が1.20でsikii0が0.9(s0>=sikii0)にもかかわらず z0に1が代入されません(s1とsikii1も同様)。 いろいろ考えてみましたが、原因が分かりませんでした。 どなたかよろしくお願いします。

  • c言語 プログラミング(初心者)

    解を判定するプログラミングを作成したのですが、a,b,cを0,1,2と入力したときに解に0.00000が出てきて解がおかしくなります。 どなたか詳しい方教えてください。また簡潔にできる点などありましたらご指摘お願いします。 #include <stdio.h> #include <math.h> int main (void) { double a,b,c,d,x1,x2; printf("ax^2+bx+c=0 の係数を入力してください\n"); scanf("%lf %lf %lf",&a,&b,&c ); if(a==0){ if(b==0) { printf("解は存在しません\n"); } else { x1=-c/b; printf("解は %f です\n",x1); } } else { d=b*b-4*a*c; if(d>=0){ x1=(-b+sqrt(d))/(2.0*a); x2=(-b-sqrt(d))/(2.0*a); if(d==0){ printf("解は %f (重解)です\n",x1); } else { printf("解は %f と %f です\n",x1,x2); } } else { printf("実数解は存在しません(虚数解)\n"); } } return 0; }

  • C言語初心者です。

    大学に入ってからC言語を授業で習い始めました。なので、すごい初歩的なことですが丁寧に教えてくださると嬉しいです。いくつか分からないことがあるので教えてください。   1・よくprintf("");なので%dや%fを使いますが、これはint(整数)の時が%dで、double(小数点付)の時に%fを使えばいいのか。 2・mul(呼び出す)、return(戻る)の意味、使い方 3・if(aaaa%4==0){ if(aaaa%100!=0)printf("閏年である。\n"); else{if(aaaa%400==0)printf("閏年である。\n"); else printf("閏年ではない。\n"); の意味は、もしaaaaが4で割り切れ、100で割り切れなかったら閏年で、そうではなく100で割り切れ400で割り切れたら閏年である。という意味でいいのか。 4・andとor,whileの使い方が分からない。 5・授業でやったことなのですが、 # include<studio.h>  int passWordInput(); main(){    int a, pw=1234, a=passWordInput(); if(a==pw)printf("ok\n"); else{a=passWordInput(); if(a==pw)printf("ok\n"); else{a=passWordInput(); if(a==pw)printf("ok\n"); else printf("Byw!!\n"); } } } int passWordInput(){ int wk; printf("パスワード:");scanf("%d",&wk); return wk; } がよく分かりませんでした。特にwkが出てくるあたりからです。 一応全て自分なりに本とか見てみましたが、あまり理解出来なかったので詳しい回答をしてくださると嬉しいです。よろしくお願いします。

  • C言語

    #include <stdio.h> int main(void) { int a=0,ans1,ans2,ans3,ans4; printf("整数を入力してください。\n"); scanf("%d",a); ans1 = a+7; ans2 = a*;8 ans3 = a%3; ans4 = a*(-1); printf("%d\n",ans1); printf("%d\n",ans2); printf("%d\n",ans3); if(a==15){ prntf("true\n",a); } else{ printf("false\n",a); } if(a != 8){ printf("true\n",a); } else{ printf("false\n",a); } if(a <= 3){ printf("true\n",a); } else{ printf("false\n",a); } printf("%d\n",ans4); if(a<2||7<a){ printf("true\n",a); } else{ printf("false\n",a); } return 0; } これを実行しようとしてもexeファイルになりません。 教えていただけませんか?

  • C言語

    forの直後で1+2+3+4+5+・・・・・・・と加算し続ける式がわからないので教えてください。 #include<stdio.h> int main(void) { char moji; int i,sum; printf("正の整数を1から順に加算します。n\"); printf("加算を開始してよろしいですか。(Y=実行。N=終了)\n"); moji=getchar(); if(moji==y) { for(i=2;sum>=1001;i++) { この部分がわかりません; printf("加算値は%dです。¥n",sum); } }else if(moji=='n'){ printf("終了します。\n"); }else{ printf("YまたはNを入力してください。\n"); } return 0; }

  • C言語でのカレンダープログラミングについて。

    今、C言語でカレンダーについてのプログラミングを行っています。 まず月を入力し表示させる。 その年がうるう年かどうか判定させる。 日曜~土曜を表示し、指定した月の日数を曜日に合わせて表示させる。 2008年1月1日は火曜日。 という事実を利用してよい。 という条件で、うるう年かの判定はあるものの年は2008年で固定です。 曜日、指定した月の日数を出すところまでいきましたが。 曜日に合わせて出す事ができません。 今は1月に合わせて、1日が火曜日のところに出るように配置してます。 が、次の週になったときにどのように改行指定すればいぃのかわりません。 また、来月以降の月初めの曜日指定もわからないです。 途中までのプログラムはこれです。 醜いかもしれませんが。 #include <stdio.h> int main(void) { int year=2008; int month,hantei=0,a,b,c; int uru[12]={31,29,31.30,31,30,31,31,30,31,30,31};/*うるう年の時の各月ごとの日数*/ int normal[12]={31,28,31,30,31,30,31,31,30,31,30,31};/*通常の年の各月ごとの日数*/ printf("表示させる月を入力してください。:"); scanf("%d",&month); if(year%4==0||year%100==0||year%400==0) { hantei=1;/*その年がうるう年かどうかを判定し、うるう年なら「hantei」に「1」が代入*/ } if(hantei==1)/*うるう年の場合。*/ { printf("%d年 %d月\n",year,month); printf("%d日\n",uru[month-1]); } else/*通常の年の場合。*/ { printf("%d年 %d月\n",year,normal[month-1]); printf("%d\n",normal[month-1]); } printf("日 月 火 水 木 金 土\n");/*曜日*/ if(hantei==1)/*うるう年の場合*/ { for(b=0;b<=7;b++) { printf(" ");/*火曜日のところまでスペースを空ける*/ } for(c=1;c<=uru[month-1];c++)/*日数表示*/ { printf("%2d ",c); } } return(0); } まだあまりC言語に詳しくないので、簡単に説明できる範囲で御願いします。 説明がわかりにくいかもしれませんが、すいません。

  • C言語の質問です

    下記の素数か素数でないか調べるコードで、 (1)変数名にis_primeとありますが、isは何を意味しているのですか? (2)is_prime = 1;とするのがわかりません。 (3)以下、return 0; まで、どういう流れかわかりません よろしければコメント以下から1行ずつ教えてもらえるとうれしいです。 #include <stdio.h> int main(void) { int num, i, is_prime; printf("判定したい数を入力してください: "); scanf("%d", &num); /* 約数があるかどうか調べる */ is_prime = 1; for(i=2; i<=num/2; i=i+1) if((num%i)==0) is_prime = 0; if(is_prime==1 && num > 1) printf("素数です"); else if (num > 1) printf("素数ではありません"); return 0; }

  • C++言語について。構文エラー

    ジャンケンゲームを作ってたんですが サイトを参考にしながらやってたんですが、どこかでミスったみたいで。 コピーしてやるのはイヤなので、自分で打ちたいんです。   どうか間違いを指摘してもらえないでしょうか?            #include <stdio.h> #include <stdlib.h> int main() { int n; int p;//player int c;//computer srand(0);//乱数の初期化 do { //プレイヤーの手 printf("あなたの手を入力してください\n(グー:1、チョキ:2、パー:3\n"); scanf("%d", &p); //コンピュータの手 c = rand() % 3 + 1; //勝ち負け判定 if(p == c){ printf("draw\n"); }else if(p == 1 && c == 2){ printf("WIN!!\n"); }else if(p == 2 && c == 3){ printf("WIN!!\n"); }else if(p == 3 && c == 2){ printf("WIN!!\n"); }else{ printf("lose...\n"); } //続けるかどうかの判定 printf("try agin?\nNO(0を入力)---"); scanf("%d", &n); //nが0以外だったら続ける }while(n != 0); return 0; }        で、エラーが構文エラー : ';' が 'return' の前にありません。 というものでした。   よろしくおねがいします。

  • C言語でのじゃんけん

    こんちには。 C言語の乱数を用いてじゃんけんプログラムを作ろうと思っているのですが、 エラーメッセージが出てしまいうまくいきません。 どこがおかしいのでしょうか? #include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int i,j,k; printf("じゃんけんをしましょう(ぐー:1、ちょき:2、ぱー:3)¥n"); for(k=k; k<=10; k++) { srand(time(NULL)); j=rand()%3+1; scanf("%d",&i); if(i==1&&j==1) printf("私はグーなので、あいこです¥n"); else if(i==1&&j==2) printf("私はチョキなので、あなたの勝ちです¥n"); else if(i==1&&j==3) printf("私はパーなので、あなたの負けです¥n"); else if(i==2&&j==1) printf("私はグーなので、あなたの負けです¥n"); else if(i=2&&j==2) printf("私はチョキなので、あいこです¥n"); else if(i==2&&j==3) printf("私はパーなので、あなたの勝ちです¥n"); else if(i==3&&j==1) printf("私はグーなので、あなたの勝ちです¥n"); else if(i==3&&j==2) printf("私はチョキなので、あなたの負けです¥n"); else if(i==3&&j==3) printf("私はパーなので、あいこです¥n"); else printf("1か2か3を入力してください¥n"); } } OS mountain lionで利用中ですが、 「じゃんけんをしましょう(ぐー:1、ちょき:2、ぱー:3)」 と表示されたまま、うまく動作しません。 教えてください。

    • ベストアンサー
    • Mac