Cプログラムが動かない理由は?

このQ&Aのポイント
  • Cプログラムを勉強中の方が、年齢に-1が入力されるまで名前、年齢、性別を聞くプログラムを作成していますが、うまく動きません。
  • 具体的には、年齢の入力がされず、名前と性別の入力がまとめて表示されてしまう問題が発生しています。
  • 解決策を教えていただきたいです。お願いします。
回答を見る
  • ベストアンサー

Cプログラムがどうしても動きません

Cを勉強中です。 年齢に-1が入力されるまで、名前、年齢、性別を聞くプログラムを作っているのですが、どうしてもうまく動きません。 具体的には、年齢を聞かれず、年齢?性別?_とまとめて表示されてしまいます。 ぜひともどこが間違っているか教えてください。お願いしますm(_ _)m #include<stdio.h> typedef struct{ char name[20]; int year; char sex[6]; }student; void read_data(int,student*); void write_data(int,student*); int main(void){ student data[10]; int i=0,j=0; do{ read_data(i,data); i++; }while(data[i-1].year!=-1); for(j=0;j<=i-1;j++){ write_data(j,data); } return 0; } void read_data(int i,student *data){ printf("%d人目\n",i); printf("名前?\n",i); scanf("%s\n",&(data[i].name)); printf("年齢?\n",i); scanf("%d\n",&(data[i].year)); printf("性別?\n",i); scanf("%s\n",&(data[i].sex)); return; } void write_data(int j,student *data){ printf("%d人目\t",j+1); printf("名前:%s",data[j].name); printf("年:%d",data[j].year); printf("性:%s",data[j].sex); return; }

  • nktos
  • お礼率29% (39/133)

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

  • ベストアンサー
  • 500cii
  • ベストアンサー率50% (14/28)
回答No.2

実行した際に 名前? aaa(改行) bbb(改行) 年齢? 性別? ccc(改行) のように名前の時に二回エンターキーを押していませんか?これは scanf("%s\n",&(data[i].name)); の\nが存在するため、aaaの改行をフォーマットの一致と判断されただけで、scanfの終了と判断されないためです。 そのためbbb(改行)というふうに他の文字を入れることで、\nの一致を終了させるのですが、このbbbが実はバッファ上に残っているのです。 そのため、年齢?の際にバッファ上に残っているbbbを参照し、不一致と判断され、即終了していたわけです。 さらに、不一致で終了しているのでまだbbbはバッファ上に残っています。 従って、性別のところでccc(改行)としていますが、これは名前の時と同じことが起きていて、 scanfはbbb(改行)ccc(改行)を処理しているためdata.sexにはbbbが代入されます。

nktos
質問者

お礼

分かりやすい回答をありがとうございました^^ 疑問が吹っ飛びました!

その他の回答 (1)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

>scanf("%s\n",&(data[i].name)); >scanf("%d\n",&(data[i].year)); >scanf("%s\n",&(data[i].sex)); scanf()の中の"\n"って必要ですか? あと……このコードだと10人以上のデータを入力しようとすると吹っ飛びます。 # 名前が20文字を越えた場合、または性別が6文字を越えた場合もメモリ破壊しますけどね。

nktos
質問者

お礼

ですよね。。。\nが問題のようです。 ありがとうございますm(_ _)m

関連するQ&A

  • Cのプログラムがどうしても動きません

    Cを勉強中なのですが、以下のプログラムがうまくいきません。 (studentは構造体で定義した型です。) iが0でない5の倍数の時にreallocでメモリを増やそうと思ったのですが、 「21行目」(reallocの行)で記述エラーを発見しました。 「lvalue」を付け忘れています。 と表示されます。 どこが間違っているのでしょうか?教えてくださいm(_ _)m #include<stdio.h> typedef struct{ char name[20]; int year; char sex[6]; }student; void read_data(int,student*); void write_data(int,student*); int main(void){ student data[5]; int i=0,j=0; do{ read_data(i,data); i++; if(i%5==0 && i!=0){ data=realloc(data,(sizeof(student))*(i+5)); } }while(data[i-1].year!=-1); } for(j=0;j<i-1;j++){ write_data(j,data); } free(heap); return 0; } void read_data(int i,student *data){ printf("%d人目\n",i); printf("名前?\n",i); scanf("%s",(data[i].name)); printf("年齢?\n",i); scanf("%d",&(data[i].year)); printf("性別?\n",i); scanf("%s",(data[i].sex)); return; } void write_data(int j,student *data){ printf("%d人目\t",j+1); printf("名前:%s\n",data[j].name); printf("年:%d\n",data[j].year); printf("性:%s\n",data[j].sex); return; }

  • プログラムの添削

    以下のような数当てゲームを作りました.なるべくうまいプログラムを書けるようになりたいのですが,どのような改善点がありますか?よろしくお願いします. /*数当てゲームを作りなさい.*/ #include<stdio.h> void maegaki(void); /*このように関数を定義しまくることに意味はあるのか?main関数はすっきりするけど.*/ void in_check_out(int i); int main(void) { int i; int j; maegaki(); for(j=0;j<10;j++) { scanf("%d",&i); in_check_out(i); if(!(i-1)) return 0; printf("残り%d回です.\n",9-j); } return 0; } void maegaki(void) { printf("数当てゲームをはじめます.\nぼくの好きな整数を当ててください.\nチャンスは10回です.\nヒントはボゾン\n"); } void in_check_out(int i) { if(!(i-1)) { printf("正解!答えは1です.\n"); } else { printf("残念!\n"); if(i>1) printf("%dより小さいです.\n",i); else printf("%dより大きいです.\n",i); } }

  • Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が

    Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が間違っているのかずっと考えているのですがいまだに解決策が見つかりません。ヒントでもいいのでお願します。 #include <stdio.h> int init(void); void show(void); int chk_cmp(void); char input(void); int move(char cmd); #define N 4 int panel[N][N] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 0}, {13, 14, 15, 12} }; int x, y; int main(void) { printf("これは15パズルです。\n" "左上から右に向かって「1」から「15」が並ぶよう,\n" "「0」を動かしてください。\n" "操作はテンキーで行います。( 8(上),4(左),6(右),2(下) )\n"); if( !init() ) { printf("パネルの初期化に失敗しました。「0」のパネルがありません。\n"); return 1; } while(1) { show(); if( chk_cmp() ) { printf("完成です!\n"); break; } while(1) { if( move(input()) ) { break; } else { printf("そっちには動かせません。\n"); } } } return 0; } int init(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(panel[i][j]==0){ x=j; y=i; return 1; } } } return 0; } void show(void) { int i,j; printf("---------------\n"); for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ printf("%3d",panel[i][j]); } printf("\n"); } printf("---------------\n\n"); } int chk_cmp(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(i==N-1&&j==N-1){ if(panel[i][j]!=0){ return 0; } }else{ if(panel[i][j]!=N*i+j+1){ return 0; } } } } return 1; } char input(void) { int comand; while(1){ scanf("%d",&comand); if(comand==8||comand==4||comand==6||comand==2){ break; } printf("8(上),4(左),6(右),2(下)を入力してください。"); } return comand; } int move(char cmd) { int dx=0, dy=0; if(cmd==8){dy=-1;}//上 if(cmd==4){dx=-1;}//左 if(cmd==6){dx=1;}//右 if(cmd==2){dy=1;}//下 if(x+dx>=0&&x+dx<=N-1&&y+dy>=0&&y+dy<=N-1){ panel[y][x]==panel[y+dy][x+dx]; panel[y+dy][x+dx]==0; y+=dy; x+=dx; return 1; } else{return 0;} }

  • 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"); }

  • プログラム

    下のようなプログラムを作ったのですが、10進2進変換をj=n>>2&1の部分にあるようなビットシフトではなく、 for(i=1;i<8;i++){printf("bit[%d]=%d\n",i,n%2);n=n/2;}に変えて剰余計算で行うプログラムにしたいのですが、分かる方がいましたら教えて下さい。お願いします。 #include <stdio.h> int main(void) { int i,j,n; i=2; printf("数字を入力="); scanf("%d",&n); printf("Dec=%d\n",n); printf("heX=0x%x\n",n); j=n>>2&1; printf("bit[%d]=%d\n",i,j); return(0); }

  • C言語プログラムについて

    wikipediaのコムソートを参考に、次のように作りました。 動きますでしょうか。動かなければ、どこをどのようにすればよいか教えていただけませんでしょうか。 プログラム「#include<stdio.h> #include<string.h> void combsort(void); void swap(void); int main(void) { combsort(); swap(); printf("データ%dの並べ替え結果は、\n%d\nです。\n"data2,data); return 0; } void combsort(){ int h,swaps,data,len,data2; printf("ソートさせる数を入力。>\n"); scanf("%d",&data); data2 = data; len = strlen(data); h = len * 10 / 13; while(true){ swapa = 0; for(i = 0;i + h <len;i++) { if(data(i) > data(i + h)) { swap(data, i, i + h); swaps +=1; } } if(h==1){ if(swaps==0){ break; } } else{ h = h * 10 / 13; } } } void swap{ int a,i,j; const int t = a[i]; a[i] = a[j]; a[j] = t; } 」 data:scanfによって入力される並べ替えを行う数値(例:0219523056810)を代入。 data2:dataのコピーで、並べ替えを行う前のデータを保管しておくもの。 また、これの反対(これが、昇順なら、降順。降順なら、昇順。)を同じようにしたいと思います。(combsort2にて)どうすればよいでしょうか。 教えていただけませんでしょうか。 お早めのご回答お待ちしております。

  • c言語 行列のn階乗のプログラム

      1 2 -1 D= 3 0 -2   -1 1 2 の3次正方行列のn乗を計算するプログラムを作成しています。 いろいろと試してみましたがうまくいきません。 どなたか教えていただけるとうれしいです。 よろしくおねがいします。 #include <stdio.h> int main(void) { int a[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} }; int b[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} }; int s[3][3]; int m,n; int i,j,k; printf("[A]^n;n = ");scanf("%d",&n); for (m=2;m <= n;m++){ for (i=0;i<3;i++){ for (j=0;j<3;j++){ s[i][j] = 0; for(k=0;k<3;k++){ s[i][j] =s[i][j] + a[i][k] * b[k][j]; } } } for(i=0;i<3;i++){ for(j=0;j<3;j++){ b[i][j]=s[i][j]; } } printf("%3d",s[i][j]); putchar('\n'); } return (0); }

  • おみくじプログラムですがじっこうできません。

    #include<stdio.h> int main() { int i; char data[5][10]={"大吉","小吉","吉","凶","大凶"}; printf("1~5の間の整数を入力:"); scanf("%d",&i); while(i<1&&i>5){ printf("入力値が不適切です。\n"); printf("1~5でお願いします。\n"); scanf("%d",&i); } printf("%s\n",data[5][i-1]); return 0; } 自分で考えてみたのですが、どうしたらいいかわかりません。

  • C言語初心者です。書いたプログラムを採点して下さい

    入力された0~100までの10個の数値から、 最小値と最大値を表示するプログラムを書きました。 #include <stdio.h> int getmin(int * pvalue); int getmax(int * pvalue); int main(void) {     int i,value[10];     int minimum,maximum;     printf("0~100の範囲で10個の数値を入力してください:\n");     for(i=0;i<10;i++){         scanf("%d",&value[i]);         if(value[i] < 0 || value[i] > 100)         {             printf("0~100の範囲です:\n");             scanf("%d",&value[i]);         }     }     minimum = getmin(value);     maximum = getmax(value);     printf("最小値は%d\n",minimum);     printf("最大値は%d\n",maximum);     return 0; } int getmin(int * pvalue) {     int i=0,j;     for(j=1;j<10;j++)     {         while(pvalue[i] > pvalue[j]){i++;}     }     return pvalue[i]; } int getmax(int * pvalue) {     int i=0,j;     for(j=1;j<10;j++)     {         while(pvalue[i] < pvalue[j]){i++;}     }     return pvalue[i]; } 正常に作動はしましたが、 記述に無駄が多い、分かりづらい などあればご指導いただけますか? よろしくお願いします。

  • cプログラム

    #include<stdio.h> /*Calc MAX of (a,b)*/ int max(int x,int y) { if(x>y) return x; else return y; } /*Calc n!*/ void fact(int n) { int i,ans; ans=1; for(i=n;i>=1;i--){ ans*=i; } printf("ans=%d\n",ans); } /*END*/ void end() { printf("Thanks\n"); exit(0); } /*Main*/ int main() { int key; int a,b,saidai; int n; while(1){ puts("\n=====Main MENU ====="); puts("1.......max(a,b)"); puts("2.......n!"); puts("9.......END\n"); printf("Input No(1,2,9)=?"); scanf("%d",&key); switch(key){ case 1: printf("Inputs:a,b?"); scanf("%d,%d",&a,&b); saidai=max(a,b); //Call max(a,b) printf("max(%d,%d)=%d\n",a,b,saidai); break; case 2: printf("Input:n?"); scanf("%d",&n); fact(n); break; case 9: end(); break; default: printf("!!!!!Miss Input_No!!!!!\n"); break; } } のプログラムなのですが、1の処理を行った場合max(a,b)の値が正しく表示されません どこを直せばいいでしょうか? return(0);

専門家に質問してみよう