C言語構造体に関するプログラムで実行結果が意味不明な文字になる問題

このQ&Aのポイント
  • C言語構造体に関するプログラムを作成し、データファイルをコマンドラインから読み込んで平均と評価を出力する際に、意味不明な文字が表示される問題が発生しています。
  • データファイルの内容は学生の成績であり、ID、名前、スコア、成績を表す構造体で管理されています。ファイルを読み込んで平均点を計算し、成績評価を付与しようとしています。
  • しかし、プログラムを実行しても正しく平均と成績が表示されず、意味不明な文字が表示されてしまいます。解決策を教えていただける方がいらっしゃいましたら、ご教示いただけると幸いです。
回答を見る
  • ベストアンサー

c言語構造体に関するプログラム

データファイルをコマンドラインから読み込み、元のファイルの内容に加えその平均と評価を出力するプログラムを作っているのですが、実行しても意味のわからない文字が羅列され更に平均等が0になってしまいます。 分かる方いらっしゃいましたら回答よろしく願いします<(_ _ )> ↓読み込むデータファイルの内容 1077001 Jack 87 70 71 92 91 1077002 Jo 67 77 75 92 71 1077003 Akira 37 60 71 52 36 (中略) 1077016 Kazu 95 97 90 95 98 以下、ソースコード #include <stdio.h> #include <stdlib.h> typedef struct{ char sid[8]; char sname[10]; int score[5]; char grade; double ave; } Record; char grade_char(double); int main(int argc, char *argv[]){ Record data[20]; FILE *fp; int i; if((fp = fopen(argv[1],"r")) == NULL){ printf("Cannot open file!\n"); exit(1); }else if(argc == 1) printf("Error! Usage: ./a.out datafilename"); i = 0; while(fscanf(fp,"%s %s %d %d %d %d %d",data[i].sid,data[i].sname,&data[i].score[0],&data[i].score[1],&data[i].score[2],&data[i].score[3],&data[i].score[4])){ i++; data[i].ave = (data[i].score[0]+data[i].score[1]+data[i].score[2]+data[i].score[3]+data[i].score[4])/5; data[i].grade = grade_char(data[i].ave); printf("%s %s %d %d %d %d %d %.1f %c\n",data[i].sid,data[i].sname,data[i].score[0],data[i].score[1],data[i].score[2],data[i].score[3],data[i].score[4],data[i].ave,data[i].grade); } fclose(fp); return 0; } char grade_char(double ave){ if(0 <= ave && ave <= 34)return 'F'; else if(35 <= ave && ave <= 49)return 'D'; else if(50 <= ave && ave <= 64)return 'C'; else if(65 <= ave && ave <= 79)return 'B'; else if(80 <= ave && ave <= 100)return 'A'; else return 0; }

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

  • ベストアンサー
  • heburusu
  • ベストアンサー率85% (140/164)
回答No.1

i++; をwhileループ終了直前(printfの下あたり)に移動してはどうでしょうか? whileに入った直後にi++してしまっているので、 fscanfする前のデータで平均値計算やprintfしているのかと思われます。

その他の回答 (1)

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.2

1の方の補足 i++;をループの最後にする fscanfの戻り評価に!=EOFを書く

関連するQ&A

  • C言語のプログラムについてご指導願えますか?

    ファイルを読み込み、そのなかにI,We,You,He,She,Theyの単語がいくつかるかカウントするプログラムを作成したいのですが、単語のカウントがうまくできません。 下記に作成したソースを記載しますので、間違っている箇所を指摘していただけませんか? #include <stdio.h> #include <stdlib.h> #include <string.h> int main( void ) { char filename[FILENAME_MAX]; int j=0; int k=0; int l=0; int m=0; int n=0; int o=0; FILE *fp; gets(filename); fp = fopen(filename,"r"); { if(fp==NULL) { printf("ERROR"); return -1; } if(strcmp("I",fp)==0) { j++; } if(strcmp("We",fp)==0) { k++; } if(strcmp("You",fp)==0) { l++; } if(strcmp("He",fp)==0) { m++; } if(strcmp("She",fp)==0) { n++; } if(strcmp("They",fp)==0) { o++; } } printf("I: %d\n",j); printf("We: %d\n",k); printf("You: %d\n",l); printf("He: %d\n",m); printf("She: %d\n",n); printf("They: %d",o); fclose(fp); return 0; }

  • 助けてください! c言語のプログラムです。

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define KAMOKU_SUU 5 #define AVE_INDEX KAMOKU_SUU typedef struct { char name[32]; int scor[KAMOKU_SUU]; int mean; } STUDENT; int round(double d) { if (d < 0) return (int)(d-0.5); else return (int)(d+0.5); } #define ARRAY_OF(a) (sizeof (a) / sizeof (a[0])) int main(int argc,char* argv[]) { int i, j,k, n; int nStudets; double avrg[KAMOKU_SUU + 1]; double stdv[KAMOKU_SUU + 1]; STUDENT *mem; char buff[80]; if (argc < 2) { printf("!パラメータ不足\n"); return 1; } nStudets = atoi(argv[1]); mem = (STUDENT*)malloc(sizeof (STUDENT) * nStudets); if (mem == NULL) { printf("!アロケーション\n"); return 2; } memset(avrg, 0, sizeof (avrg)); memset(stdv, 0, sizeof (stdv)); printf("生徒 %d 名分の成績を入力してください:\n", nStudets); for (k = 0; k < nStudets; k++) { printf("%d 人目の点数と名前 > ", k + 1); gets(buff); strcpy(mem[k].name, strtok(buff," ")); mem[k].mean = 0; for (j = 0; j < KAMOKU_SUU; j++) { int i = mem[k].scor[j] = atoi(strtok(NULL," \n")); mem[k].mean += i; avrg[j] += i; stdv[j] += i * i; } mem[k].mean = round(mem[k].mean * 1.0 / KAMOKU_SUU); } for(j = 0; j < KAMOKU_SUU; j++) { avrg[AVE_INDEX] += avrg[j]; stdv[AVE_INDEX] += stdv[j]; avrg[j] = avrg[j] / nStudets; stdv[j] = sqrt(stdv[j] / nStudets - avrg[j] * avrg[j]); } n = nStudets * KAMOKU_SUU; avrg[AVE_INDEX] = avrg[AVE_INDEX]/ n; stdv[AVE_INDEX] = sqrt(stdv[AVE_INDEX] / n) - (avrg[AVE_INDEX] * avrg[AVE_INDEX]); printf("\n成績表\n"); printf("# NAME"); for (i = 1; i <= KAMOKU_SUU; ++i) printf(" #%d ", i); printf("MEAN\n"); for (k = 0; k< nStudets; k++) { printf("%d %10s",k+1,mem[k].name); for (j = 0; j < KAMOKU_SUU; j++) { printf(" %3d",mem[k].scor[j]); } printf(" %3d\n",mem[AVE_INDEX].mean); } printf("------------------------------------\n"); printf(" %10s","average"); for(j = 0; j < ARRAY_OF (avrg);j++) { printf(" %3.0f",avrg[j]); } printf("\n"); printf(" %10s","st.dev."); for ( j = 0; j < ARRAY_OF (stdv); j++) { printf(" %3.0f",stdv[j]); } printf("\n"); printf("正常終了\n"); return 0; }  実行してもできません。原因が全く分かりません。 お願いします。 修正してくださるとありがたいです。

  • C言語のソートについて

    C言語で下記のファイルの中身を昇順と降順で出力しようとしているのですが、ソートが上手くいっていない状況です。 どなたか修正点を教えて頂けないでしょうか? 「ファイルの中身」 2022/11/14 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/14 16:20:18 8+8,16.000000 2022/11/15 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/18 16:20:18 8+8,16.000000 2022/11/17 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/14 16:20:18 8+8,16.000000 「ソースコード」 #include <stdio.h> #include <string.h> #include <stdlib.h> int cmp_u(const void* a, const void* d) { return *(char*)a - *(char*)d; } int cmp_d(const void* a, const void* d) { return *(char*)d - *(char*)a; } int main() { int r,i,n; FILE* fp; char sin[9][1000]; fp = fopen("log.txt", "r"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } for (i = 0; i < 9; i++) { fscanf(fp, "%s", &(sin[i])); } fclose(fp); printf("ASC or DESC: "); scanf(" %s", &ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, 9, sizeof(char), cmp_u); } else { qsort(sin, 9, sizeof(char), cmp_d); } for (i = 0; i < 9; i++) { printf("%s\n", sin[i]); } return 0; }

  • C言語のqsortについて

    現在、qsortのコードに取り組んでいます。 if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } 恐らくこちらのqsortでの第二引数が書き方を間違えていると思うのですが、修正の方法が分からず、どなたか教えて頂けないでしょうか? #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> static char ad[10]; int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int r,i; FILE* fp; char c[11]; char sin[1000][1000]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { r = scanf("%d%c%d", &num1, &op, &num2); if (r != 3) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); scanf("%s\n", &c); if (strcmp(c, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); int cnt = 0; for (i = 0;i < 1000;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • C言語 構造体でつまずいています

    以下、番号と点数を入力して構造体配列に入力し、番号に0が入力されたら、入力処理をやめ、平均点を表示するプログラムです。  今のコードでは、最初から番号に0を入力すると、0除算になりエラーになります。どうすれば良いのでしょうか? #include <stdio.h> #define MAX 50 //配列の要素数を定義 int count=0; //グローバル変数 struct data { //構造体の定義 int num; //メンバの宣言 int ten; }; void nyuryoku(struct data *); //プロトタイプ宣言 float heikin(struct data *); //プロトタイプ宣言 void main() { struct data score[MAX]; //構造体の宣言 printf("**学生番号/点数入力**\n"); printf("\n"); nyuryoku(score); //nyuryoku関数呼び出し printf("\n**以上%d名の平均点:%0.1f点**\n",count,heikin(score)); //heikin関数の戻り値表示 } //nyuryoku関数 //機能:構造体配列にデータを入力する void nyuryoku(struct data *pd) //仮引数pdに構造体ポインタが渡る { int i; for(i=0;i<MAX;i++){ printf("学生番号>>"); scanf("%d",&pd->num); if(pd->num==0){ //学生番号に0を入力するとループを抜ける break; } printf("点  数>>"); scanf("%d",&pd->ten); count++; //人数のカウント pd++; //構造体配列を一つずらす } } //heikin関数 //機能:構造体配列の点数の平均を計算、戻り値として返す float heikin(struct data *pd) //仮引数pdに構造体ポインタが渡る { int i; int sum=0; float ave=0; for(i=0;i<MAX;i++){ if(pd->num==0){ break; } else{ sum+=pd->ten; //点数を加算 pd++; } } ave=(float)sum/count; //平均値を求める return(ave); //平均値を戻り値として返す }

  • ファイル操作やポインタ、構造体について(C言語)

    C言語の課題で詰まってしまいました。宜しければ助言を宜しくお願いします。 コマンド選択で,0) 終了,1) 追加,2) 検索(id),3)変更 が行える学生成績管理プログラムを作成する。 データは,学生の番号 名前 GP 総単位数 形で学生のデータを持っているファイルである。 #include<stdio.h> #include<stdlib.h> #include<string.h> struct student{ int id; char name[25]; int gp; int credit; }; void add(char *, struct student);//追加 int search(char *, struct student *);//検索 void change(char *, struct student);//指定したidの学生の情報を変更 main(int argc,char *argv[]) { FILE *fp; int i = 0; int num; struct student students; if(argc == 1){ printf("set filename\n"); return 1; } while(1) { printf("1)add 2)search 0)quit "); scanf("%d",&num); if(num == 0) break; /* 追加 */ if(num == 1) { printf("id name gp credit ? "); scanf("%d %s %d %d", &students.id, students.name, &students.gp, &students.credit); add(argv[1], students); } /* 検索 */ if(num == 2) { printf("id ? "); scanf("%d", &students.id); if(search(argv[1],&students)){ printf("%d %s %d %d\n", students.id, students.name, students.gp, students.credit); } else{ printf("ID %d Not Found.\n",students.id); } } if(num == 3){ //変更 } } } /* 追加ルーチン */ void add(char *filename, struct student students) { FILE *fp; if((fp = fopen(filename, "a")) == NULL){ printf("can't open %s\n", filename); exit(1); } fprintf(fp,"%d %s %d %d\n", students.id, students.name, students.gp, students.credit); fclose(fp); } /* 検索ルーチン */ int search(char *filename, struct student *students) { FILE *fp; int id; char name[25]; int gp; int credit; if((fp = fopen(filename, "r")) == NULL){ printf("can't open %s\n", filename); exit(1); } while(fscanf(fp,"%d %s %d %d", &id, name, &gp, &credit) != EOF) { if(id == students->id){ students->id = id; strcpy(students->name ,name); students->gp = gp; students->credit = credit; return 1; } } return 0; fclose(fp); } /* 変更ルーチン */ void add(char *filename, struct student students){ } ------------ここまで------------ ファイルの操作での入出力は"a"や"r"、また"w"を利用するのかとも思いましたが、 指定したIDの内容を書き換えるにはポインタを2つ使う方法しか思いつかないのですが、与えられた問題で、変更のプロトタイプは void change(char *, struct student); となっていて、どうやるのかまったく見当もつきません。 稚拙な文で伝わりにくいかもしれませんが、 変更のやり方についてご教授願います。 見難くて申し訳ありません。 どうか宜しくお願いします。

  • C言語 単語を取得するプログラム

    ファイルからアルファベットをスペース等で区切って取得するプログラムを作成しているのですが、デバグがうまくいきません。 どの部分がプログラム的におかしいか、どうすればよいか教えていただけませんでしょうか。 テキスト I have a pen. if you have a pen, please lend me your pen. abc, def.ghi jkl mno pqr..,stu vwx .yz ソースプログラム #include<stdio.h> #include<string.h> int word(char data[],FILE *fp){ char c; int n=0; data[0]='\0'; while((c=fgetc(fp))!=EOF){ if(c!=' ' && c!=',' && c!='.'){ n=strlen(data); data[n]=c; data[n+1]='\n'; } else return(n); } return(0); } int main(){ FILE *fp; char data[30]; fp=fopen("test.txt","r"); if((fp = fopen("test.txt","r"))==NULL){ printf("no file\n"); exit(1); } while((word(data,fp)!=0)){ printf("%s \n",data); } fclose(fp); return(0); }

  • この間質問した内容です。

    この間質問した内容です。 #include <stdio.h> #include <stdlib.h> #include <string.h> int knum; int kNO; char **kstr; int *ans; int get_score(void) {  FILE *fp;  int best;  if((fp = fopen("score.txt","r")) == NULL)  {   printf("初回起動ですね。\nスコアファイルを新規作成します。\n");   best = 0;  }  else  {  fscanf(fp,"%d%d",&best,&knum);  printf("最高点は%d問中%d問です。\n",knum,best);  fclose(fp);  } } int read_kuizu(void) {  int i;  FILE *fp;  if((fp = fopen("kuizu.txt","r")) == NULL) return(-1);  fscanf(fp,"%d",&kNO);  if((kstr = (char **)calloc(kNO,sizeof(char *))) == NULL) return(-1);  if((ans = (int *)calloc(kNO,sizeof(int))) == NULL) return(-1);  for(i = 0; i<kNO; i++)  {   char temp[1024];   size_t len;   fscanf(fp,"%s",temp);   fscanf(fp,"%d",&ans[i]);   len = strlen(temp);   if((kstr[i] = (char *)malloc(len + 1)) == NULL) return(-1);   strcpy(kstr[i],temp);  }  fclose(fp);  return(0); } int kuizu_game(void) {  int i;  int score = 0;  for(i = 0; i<kNO; i++)  {   int unans;   printf("\nクイズ%d\n", i + 1);   printf("%s YES(0)/NO(1)\n",kstr[i]);   do   {    printf("答を選んで番号を入力して下さい。=>\n");    scanf("%d",&unans);   }   while(unans!=0 && unans!=1);   if(unans == ans[i])   {    score++;    printf("正解です!\n");   }   else   printf("残念ながら不正解・・・\n");   }   return(score); } void result(int best,int score) {  printf("\n今回%d問中%d問正解でした。\n",kNO,score);  printf("前回は%d問中%d問正解していました。\n",knum,best); } int main(void) {  int score;  int best;  best = get_score();  if(read_kuizu() == -1)  {   printf("エラー\n");   return(-1);  }  score = kuizu_game();  result(best,score);  if(score>best)  {   printf("最高点を更新!\n");   best = score;  }  FILE *fp;  fp = fopen("score.txt","w");  fclose(fp);  return(0); } 一応ここまでやってコンパイルしたのですが、クイズのファイルを読み込む事ができません。どこか間違ってるんでしょうか?

  • C言語のプログラム組んだのですが完成させてください

    C言語のプログラムを断片的に作成したのでつなげて完成させて頂けないでしょうか? このサイトでコンパイルなど出来ます http://ideone.com/ 以下の問題を解きました また問題文の指示には必ずしたがってください。また、この文章の条件でなく、人数が4人とかそれ以外の時でも出来るようなプログラムでお願いします。 http://i.imgur.com/nuzJv2v.png http://i.imgur.com/c7f3Vh2.png http://i.imgur.com/5aCqDO0.png http://i.imgur.com/9u8hHIM.png 問題は画像になっています #include<stdio.h> #include<string.h> /*構造体型struct Dataの宣言*/ struct Data{ char name[20]; int height; double weight; } data[100]; int cnt; int main(void) { int a; do { printf("**************身長・体重の表示***************\n\n"); printf(" データファイルの読み込み・・・・・(1)\n"); printf(" 全てのデータを表示・・・・・・・・(2)\n"); printf(" 特定のデータを表示・・・・・・・・(3)\n"); printf(" 終わり・・・・・・・・・・・・・・(4)\n\n"); printf("処理番号を入力してください\n"); scanf("%d",&a); } while(a<1 || a>4); return a; } /*read_file関数の宣言*/ int read_file(void) { FILE *fp; char filename[20]; cnt=0; printf("読み込むファイルの名前を入力してください。\n"); scanf("%s",filename); fp=fopen(filename,"r"); if(fp==NULL){ printf("ファイルをオープンできませんでした。\n"); return 1; } while(fscanf(fp,"%c %d %lf",data[cnt].name,data[cnt].height,data[cnt].weight)!=EOF){ cnt++; fclose(fp); printf("ファイルを読み込みました。\n"); } return 0; } /*p_all関数の宣言*/ int p_all(void) { int i; printf("名前 身長(cm) 体重(kg)\n"); for(i=0;i<cnt;i++) { printf("%-2s %5d %.2f\n",data[i].name,data[i].height,data[i].weight); } } 最初の処理番号を入力した所で終わってしまいます、何とか改変してくださいお願いします 補足

  • C言語について教えてください

    ファイルの文を読み込み、I、Weなどの定めた単語の数を数えるプログラムを作りたいのですが、うまくいきません。 具体的な問題点は、単語の数を数える際、一致する単語があった場合、再び最初から文を見直すため、無限ループしてしまう。 We,WE、weなど大文字小文字の違いで単語が数えられないなどです。 #include <stdio.h> #include <stdlib.h> #include <string.h> int main( void ) { char filename[FILENAME_MAX]; int j=0; int k=0; int l=0; int m=0; int n=0; int o=0; int w; char str[50]; FILE *fp; gets(filename); fp = fopen(filename,"r"); { if(fp==NULL) { printf("ERROR"); return -1; } } fscanf(fp,"%50s",str); for(w=0;w<=j+k+l+m+n+o;w++) { if(strcmp("I",str)==0) { j++; } if(strcmp("We",str)==0) { k++; } if(strcmp("You",str)==0) { l++; } if(strcmp("He",str)==0) { m++; } if(strcmp("She",str)==0) { n++; } if(strcmp("They",str)==0) { o++; } } printf("I: %d\n",j); printf("We: %d\n",k); printf("You: %d\n",l); printf("He: %d\n",m); printf("She: %d\n",n); printf("They: %d",o); fclose(fp); return 0; }

専門家に質問してみよう