• ベストアンサー

学生番号が正常に出力されていません

この質問と同じ質問が他に1つありますが、何分急いでいますのでご了承下さい。以下のプログラムで実行結果が、入力された得点に対応する学生番号を得点の高い順に並び替えて出力したいのです。得点の方は正常に出力されているのですが学生番号がおかしな出力になっています。しかし、どこをどう直せば良いか分かりません。なので分かりやすく説明お願い致します。 #include<stdio.h> #define M 10 #define N 5 void sort_score(int score_cpy[M]); int linear_search(int score_cpy[M],int key); void exchange_number(int order[M],char number[M][N]); int no; int main(void) { int i,score[M],score_cpy[M],order[M]; char number[M][N]; printf("人数を入力して下さい:"); scanf("%d",&no); ("学生番号と平均点を入力して下さい。"); for(i=0;i<no;i++){ printf("学生番号:"); scanf("%s",&number[i][N]); printf("得点:"); scanf("%d",&score[i]); } for(i=0;i<=M;i++){ score_cpy[i]=score[i]; } sort_score(score_cpy); for(i=0;i<M;i++){ order[i]=linear_search(score_cpy,score[i]); } exchange_number(order,number); printf("\n\n得点の高い順に並び替えて表示します\n\n"); for(i=0;i<no;i++){ printf("学生番号 :%s %d点\n",number[i],score_cpy[i]); } return 0; } void sort_score(int score_cpy[M]) { int i,j,score; for(j=0;j<no-1;j++){ for(i=no-1;i>0;i--){ if(score_cpy[i-1]<score_cpy[i]){ score=score_cpy[i-1]; score_cpy[i-1]=score_cpy[i]; score_cpy[i]=score; } } } } int linear_search(int score_cpy[M],int key) { int i; for(i=0;i<no;i++){ if(score_cpy[i]==key){ return i; } } return -1; } void exchange_number(int order[M],char number[M][N]) { int i,temp[M]; for(i=0;i<M;i++){ if(order[i]==-1)break; temp[i]=number[i][N]; } for(i=0;i<M;i++){ if(order[i]==-1)break; number[order[i]][N]=temp[i]; } } 人数を入力して下さい:10 学生番号:y3051 得点:85 学生番号:y3052 得点:65 学生番号:y3053 得点:75 学生番号:y3054 得点:63 学生番号:y3055 得点:95 学生番号:y3056 得点:68 学生番号:y3057 得点:80 学生番号:y3058 得点:90 学生番号:y3059 得点:83 学生番号:y3060 得点:70 得点の高い順に並び替えて表示します 学生番号 : 95点 学生番号 :y3051y3052y3053y3054y3055y3056y3057y3058y3059y3060 90点 学生番号 :y3052y3053y3054y3055y3056y3057y3058y3059y3060 85点 学生番号 :y3053y3054y3055y3056y3057y3058y3059y3060 83点 学生番号 :y3054y3055y3056y3057y3058y3059y3060 80点 学生番号 :y3055y3056y3057y3058y3059y3060 75点 学生番号 :y3056y3057y3058y3059y3060 70点 学生番号 :y3057y3058y3059y3060 68点 学生番号 :y3058y3059y3060 65点 学生番号 :y3059y3060 63点

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

  • ベストアンサー
回答No.3

いろいろ突っ込みが入りそうですが、あなたのプログラムの原型をできる限りいじらずに作ってみました。変更箇所には変更のコメントを入れてあります。 #include<stdio.h> #include <string.h> //変更 strcpyを使用するときに必要 #define M 10 #define N 6 //変更 学生番号が5桁なら5+1=6桁分の領域が必要 void sort_score(int score_cpy[M]); int linear_search(int score_cpy[M],int key); void exchange_number(int order[M],char number[M][N]); int no; int main(void) { int i,score[M],score_cpy[M],order[M]; char number[M][N]; printf("人数を入力して下さい:"); scanf("%d",&no); ("学生番号と平均点を入力して下さい。"); for(i=0;i<no;i++){ printf("学生番号:"); scanf("%s",number[i]);//変更 &number[i][0]でもOK printf("得点:"); scanf("%d",&score[i]); } for(i=0;i<=M;i++){ score_cpy[i]=score[i]; } sort_score(score_cpy); for(i=0;i<M;i++){ order[i]=linear_search(score_cpy,score[i]); } exchange_number(order,number); printf("\n\n得点の高い順に並び替えて表示します\n\n"); for(i=0;i<no;i++){ printf("学生番号 :%s %d点\n",number[i],score_cpy[i]); } return 0; } void sort_score(int score_cpy[M]) { int i,j,score; for(j=0;j<no-1;j++){ for(i=no-1;i>0;i--){ if(score_cpy[i-1]<score_cpy[i]){ score=score_cpy[i-1]; score_cpy[i-1]=score_cpy[i]; score_cpy[i]=score; } } } } int linear_search(int score_cpy[M],int key) { int i; for(i=0;i<no;i++){ if(score_cpy[i]==key){ return i; } } return -1; } void exchange_number(int order[M],char number[M][N]) { int i; char tmp[M][N]; //変更 numberの退避領域なので、numberと同じ型 for(i=0;i<M;i++){ if(order[i]==-1)break; strcpy(tmp[i],number[i]); //変更 文字列のコピーはstrcpyを使用 } for(i=0;i<M;i++){ if(order[i]==-1)break; strcpy(number[order[i]],tmp[i]); //変更 文字列のコピーはstrcpyを使用 } }

freezeb
質問者

お礼

先ほど、実際にプログラムを書きなおし起動させてみると見事に実行結果通りの正常な値が出ました!。本当にありがとうございます。

その他の回答 (2)

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

> printf("人数を入力して下さい:"); > scanf("%d",&no); > ("学生番号と平均点を入力して下さい。"); > for(i=0;i<no;i++){ > printf("学生番号:"); > scanf("%s",&number[i][N]); > printf("得点:"); > scanf("%d",&score[i]); > } 学生番号をscanfする時に読み込むアドレスが違うからでしょう 正しくは scanf("%s",&number[i][0]); ではないでしょうか

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

Cでの文字列の基本を忘れてます。 終端記号'\0'がつくので、見掛け上の文字数+1の領域が必要です。

関連するQ&A

  • 整数型配列と2次元文字型配列の入れ替え方

    以下のプログラムを実行結果のように作りたいのですがexchange_numberの中身の書き方(配列の入れ替え方)が分らないので教えて下さい。 #include<stdio.h> #define M 10 #define N 5 void sort_score(int score_cpy[M]); int linear_search(int score_cpy[M],int key); void exchange_number(int order[M],char number[M][N]); int no; int main(void) { int i,number[M][N],score[M],score_cpy[M],order[M]; printf("人数を入力して下さい:"); scanf("%d",no); ("学生番号と平均点を入力して下さい。"); for(i=0;i<M;i++){ printf("学生番号:"); scanf("%s",&number[i][N]); printf("得点:"); scanf("%d",&score[i]); } for(i=0;i<=M;i++) score_cpy[i]=score[i]; sort_score(score_cpy); for(i=0;i<M;i++){ order[i]=linear_search(score_cpy,score[i]); } exchange_number(order,number); printf("\n\n得点の高い順に並び替えて表示します\n\n"); for(i=0;i<no;i++) printf("学生番号 :%s %d点\n",number[i],score_cpy[i]); return 0; } void sort_score(int score_cpy[M]) { int i,j,score; for(j=0;j<no-1;j++){ for(i=no-1;i>0;i--){ if(score_cpy[i-1]<score_cpy[i]){ score=score_cpy[i-1]; score_cpy[i-1]=score_cpy[i]; score_cpy[i]=score; } } } } int linear_search(int score_cpy[M],int key) { int i; for(i=0;i<no;i++){ if(score_cpy[i]==key){ return i; } } return -1; } void exchange_number(int order[M],char number[M][N]) {?} ちなみに実行結果は以下の通りです。 人数を入力して下さい:10 学生番号と平均点を入力して下さい。 学生番号:y3051 得点:85 学生番号:y3052 得点:65 学生番号:y3053 得点:75 学生番号:y3054 得点:63 学生番号:y3055 得点:95 学生番号:y3056 得点:68 学生番号:y3057 得点:80 学生番号:y3058 得点:90 学生番号:y3059 得点:83 学生番号:y3060 得点:70 得点の高い順に並び替えて表示します 学生番号:y3055 95 点 学生番号:y3058 90 点 学生番号:y3051 85 点 学生番号:y3059 83 点 学生番号:y3057 80 点 学生番号:y3053 75 点 学生番号:y3060 70 点 学生番号:y3056 68 点 学生番号:y3052 65 点 学生番号:y3054 63 点 プログラム中で間違えがありましたら指摘して頂けると幸いです。それで良いお待ちしております。

  • javaプログラムについて

    * クラスの出席番号順にString型配列nameに名前が、 * int型配列scoreにテストの点数が格納されています。 * * 出席番号1 大悟 74点 * 出席番号2 琴音 70点 * 出席番号3 勇輝 88点 *       ・ *       ・ *       ・ *       ・ *       ・ * * このクラスの最高得点者の名前と、最低得点者の名前を * 表示するメソッドを作成してください。 * */ public class MethodAdd8 { public static void main(String[] args){ String[] name = {"大悟", "琴音","勇輝","葵","綾乃","和樹","凛","愛花","結愛","孝太郎"}; int[] score = {74,70,88,82,96,64,80,61,72,79}; //メソッドの呼び出し int max=saikou(score); //最高得点メソッドへ System.out.println(max); int min=saitei(score); //最低得点メソッドへ System.out.println(min); } //ここにメソッドを追加してください public static int saikou(int[] score){ //最高得点者メソッド int max=score[0]; for(int i=1; i<score.length; i++){ if(score[i]>max) max=score[i]; } return max;//値を返す } public static int saitei(int[] score){ //最低得点メソッド int min=score[0]; for(int i=1; i<score.length; i++){ if(score[i]<min) min=score[i]; } return min;//値を返す } } これで最高得点と最低得点は表示されるのですが、ここからどうやって最高得点者「綾乃」と最低得点者「愛花」を表示するのか分かりません。どなたか御教授お願い致します。

    • ベストアンサー
    • Java
  • c言語 ファイル出力について

    このようなプログラムを作成しました。 エクセルでファイルを出力したいのですが… ファイルは作成できたものの、内容が書かれていません。 とても困っています↓ 自分の力不足なのでしょうがどなたかお願いします。 #include <stdio.h> #include <process.h> #define S 256 #define I 100 #define J 100 #define K 3 //グループの数 void sum(int u[][J],int N,int n); void sort(int y[],int N,int u[][J],int n); void group(int num[],int u[][J],int N,int n); void passege(int groupm[][J],int groupn,int u[][J],int n,int N); void main (void) { FILE *fp; int N=0,i=0,j=1,kou=0,n; //N:人数 n:問題数 static int u[I][J]; char buf[S]; //ファイルオープン if ((fp=fopen("data_i2_3.csv","r"))==NULL){ printf("Can't open File\n"); exit(1); } // 問題数のカウント fgets(buf,S,fp); N+=1; while(buf[i]!='\n'){ kou=kou++; i+=1; } for(i=0;i<=kou;i=i+2){ u[N][j]=buf[i]-'0'; j=j++; } n=kou/2+1; // レコードの読み込み while (fgets(buf,256,fp)!=NULL){ N+=1; // 文字型から数値型へ変換 j=1; for(i=0;i<=kou;i=i+2){ u[N][j]=buf[i]-'0'; j=j++; } } sum(u,N,n); fclose(fp); } void sum(int u[][J],int N,int n) { static int y[I]; int i,ii; //学習者iの得点の初期化 for(i=0;i<=I;i++) y[i]=0; //学習者iの得点の計算 for(i=1;i<=N;i++){ for(ii=1;ii<=n;ii++){ y[i]+=u[i][ii]; } } sort(y,N,u,n); } void sort(int y[],int N,int u[][J],int n) { int left,right,i,shift,t,v; static int num[I]; //学習者の番号記憶用変数numの初期化 for(i=0;i<=I;i++) num[i]=0; for(i=1;i<=N;i++) num[i]=i; //シェーカーソート left=0; right=N; while (left<right){ for(i=left;i<right;i++){ if(y[i]>y[i+1]){ t=y[i]; v=num[i]; y[i]=y[i+1]; num[i]=num[i+1]; y[i+1]=t; num[i+1]=v; shift=i; } } right=shift; for(i=right;i>left;i--){ if(y[i]<y[i-1]){ t=y[i]; v=num[i]; y[i]=y[i-1]; num[i]=num[i-1]; y[i-1]=t; num[i-1]=v; shift=i; } } left=shift; } group(num,u,N,n); } void group(int num[],int u[][J],int N,int n) { int groupn,i,j,k=1; //groupn:グループの人数 static int groupm[K][I]; //groupm:グループのメンバー groupn=N/K; for(i=0;i<K;i++){ for(j=0;j<groupn;j++){ groupm[i][j]=num[k]; k+=1; } } passege(groupm,groupn,u,n,N); } void passege(int groupm[][J],int groupn,int u[][J],int n,int N) { FILE *f; int i,j,k=0,l,tt; static int t[I]; //各グループの正解率 double p[K][J],pp=0.0; //初期化 for(i=0;i<K;i++){ for(j=0;j<J;j++){ p[i][j]=0; t[i]=0; } } for(i=0;i<K;i++){ for(j=0;j<groupn;j++){ t[k]=groupm[i][j]; k+=1; } } k=0; for(i=0;i<K;i++){ for(j=1;j<=n;j++){ for(l=0;l<groupn;l++){ tt=t[k]; pp=pp+u[tt][j]; k+=1; } p[i][j]=pp/groupn; pp=0.0; if(i==0) k=0; else k=groupn*i; } k=groupn*(i+1); } //ファイル出力 f=fopen("test1.csv","w"); //確認 putchar('\n'); for(i=0;i<K;i++){ for(j=1;j<=n;j++){ printf("%d群の項目%dの正解率は%fです\n",i,j,p[i][j]); } } //ファイルを閉じる fclose(f); }

  • Javaプログラムについての質問です。

    * クラスの出席番号順にString型配列nameに名前が、 * int型配列scoreにテストの点数が格納されています。 * * 出席番号1 大悟 74点 * 出席番号2 琴音 70点 * 出席番号3 勇輝 88点 * ・ * ・ * ・ * ・ * ・ * * このクラスの最高得点者の名前と、最低得点者の名前を * 表示するメソッドを作成してください。 * */ public class MethodAdd8 { public static void main(String[] args){ String[] name = {"大悟", "琴音","勇輝","葵","綾乃","和樹","凛","愛花","結愛","孝太郎"}; int[] score = {74,70,88,82,96,64,80,61,72,79}; int maxind = saikouind(score); System.out.println(name[maxind]); int minind = saiteiind(score); System.out.println(name[minind]); } //ここにメソッドを追加してください public static int saikouind(int[] score) { int ind = 0; int max = score[0]; for (int i = 1; i < score.length; i++) { if (score[i] > max) { ind = i; max = score[i]; } } return ind; //値を返す } public static int saiteiind(int[] score) { int ind = 0; int min = score[0]; for (int i = 1; i < score.length; i++) { if (score[i] < min) { ind = i; min = score[i]; } } return ind; //値を返す } これで名前は表示されるようになったのですが、 これをreturnを返さず表示するにはどうすればよいでしょうか? 色々試しているんですが、何故か名前が表示されなくなります。 丸投げしてしまうのですが、どうか知恵をお貸しください。 よろしくお願い致します。

  • C言語 プログラムの質問

    下記の問題はすでに他で回答されていますが、私のプログラムのどこがいけないかチェックしていただけませんか? 1)101人以下のクラスがあり、学生には1から通し番号が付いているものとする。 このクラスのある科目の得点を通し番号順にキーボードから受けとり、負の得点が入力されたら全員の入力が終わったものとする。 その後、キーボードから入力された番号の人の得点をxx点と漢字で表示し、存在しない番号が入力されたらプログラムを終了する。 2)第 1 種の定形外通常郵便物の料金は、次の表のように定められている。 郵便物の重さを g 単位で入力すると、料金が出力されるプログラムを作成しなさい。 ただし、以下の点を考慮すること。 *重さと料金の表は、2 次元配列として取り扱うこと *指定された範囲外の値(負の値,0,4001以上)が入力された場合は、正しい値が入力されるまで入力処理を繰り返すこと   重さ  料金   50gまで  120円   100gまで  140円   150gまで  200円   250gまで  240円   500gまで  390円  1000gまで  580円  2000gまで  850円  4000gまで  1150円 ----------------------------------------- 自分のプログラム 1) #include <stdio.h> int main(void) { int Snumber[101],score[101],i,n; for(i=0;i<101;i++){ scanf("%d",&score[i]); if(score[i]<0){ break; } } for(n=0;n<i;n++){ if(score[i-1]==''){ break; } printf("学生番号:%d\n %d\n",Snumber[i],score[i-1]); } } ----------------------------------------------- 2) #include <stdio.h> int main(void) { int weight,i; int array[8][2] = { {50,120}, {100,140}, {150,200}, {250,240}, {500,390}, {1000,580}, {2000,850}, {4000,1150}, }; scanf("%d",&weight); for(i=0;i<8;i++){ if(weight<=0){ break; }else if(weight>= 4001){ break; }else if(weight <= array[i][0]){ printf( "料金 : %d円\n", array[ i ][ 1 ] ); } } }

  • 空き番号探し

    空き番号判定がよくわからないです。 順番を変える処理をする。 順番は1から5まで。 変えようとする番号(s_no)がなければそのまま変えたらいいですが、 同じ番号がすである場合 下から5まで空き番を探す 空き番がある→ s_noと同じ番号は空き番未満まで1ずつ増やす。  空き番がない(上に空き番が生じる、s_noと同じ番号)→ s_noと同じ番号は空き番まで1ずつ減らす。 空き番をどう判定するかわからないですし、処理の流れもどうすればいいか悩んでます。 アドバイスお願いします。 説明が下手なので画像を添付しました。(パターン例) int AAA = 5; int s_no; int i; int data[5]; for(i=0;i<AAA;i++){ /* 空き番判定 */ }

  • 万年カレンダー

    万年カレンダーの日にちが、一日ずれて表示されますのでその原因を教えてください。 void main() { int nen,tuki,niti; int ff,i,n; int carender[6][7]; niti=0; for(i=0;i<6;i++)for(n=0;n<7;n++) carender[i][n]=0; printf("西暦(4桁)→"); scanf("%d",&nen); printf("month:"); scanf("%d",&tuki); ff=youbi_chk(nen,tuki,1); for(i=ff;i<7;i++) {carender[0][i]=niti;++niti;} for(n=1;n<6;n++){ for(i=0;i<7;i++){ if(niti<=niti_chk(tuki,nen)) {carender[n][i]=niti;++niti;}} } printf(" SUN MON TUE WED THU FRI SAT\n"); for(n=0;n<6;n++){ for(i=0;i<7;i++) if(carender[n][i]==0)printf(" ");else printf("%4d",carender[n][i]); printf("\n");} } int youbi_chk(int y,int m,int d) { int youbi; if(m<3) {y--; m+=10;} else {m-=2;} youbi=(y+(y/4)-(y/100)+(y/400)+(13*m-1)/5+d)%7; return youbi; } int uru_chk(int y) { if(y%400==0) return 1; if(y%100==0) return 0; if(y%4==0) return 1; return 0; } int niti_chk(int m,int y) { int hi[12]={31,28,31,30,31,30,31,31,30,31,30,31}; hi[1]+=uru_chk(y); return hi[m-1]; } プロトタイプ宣言は、省いてます。

  • C言語 教えて下さい!!!

    教えてください!! data01.txt というテストの得点が書き込んであるテキストファイルから得点を読み込んで、得点順に並べ替えて表示させるプログラミングなんですがコンパイルは成功します。 しかし、実行してみると全く違う結果になってしまいます。 どこが間違っているのか指摘してください。 #include <stdio.h> /* 構造体の宣言 */ struct data { int score; int rank; }d; /* 関数 */ void rank(struct data *x, int n) { int i, j; for ( i=0; i<n; i++) x[i].rank = 1; for ( i=0; i<n; i++) for ( j=0; j<n; j++) if(x[i].score < x[j].score) x[i].rank++; } /* main文 */ int main(void) { int a; struct data x[50]; /* ファイルから得点を読み込む */ FILE *fp; fp = fopen("data01.txt", "r"); for ( a=0; a<50; a++) x[a] = atoi(getc(fp); fclose(fp); /* 順位付け */ a = 50; rank(x,a); printf("Rank Score\n"); for ( a=0; a<50; a++) printf("%d %d\n", x[a].rank, x[a].score); return 0; } ちなみに data.txt は 左側の列は番号 右側の列が得点 1 50 2 62 3 73 4 42 5 99 6 10 7 68 8 54 9 87 10 98 11 54 12 30 13 15 14 60 15 78 16 98 17 65 18 75 19 32 20 99 21 80 22 64 23 52 24 31 25 99 26 10 27 20 28 5 29 65 30 53 31 54 32 35 33 45 34 23 35 26 36 97 37 88 38 99 39 56 40 42 41 32 42 56 43 56 44 54 45 0 46 54 47 80 48 99 49 54 50 56

  • C言語 最も小さい数

    #include <stdio.h> #define NUMBER 5 int min_of(const int vc[ ], int no){ int i; int min=vc[0]; for(i=1;i<no;i++) if(vc[i]<min){ min=vc[i]; return(min); } } int main(void) {int a[NUMBER],i=0; for(;i<NUMBER;i++){ scanf("%d",&a[i]); } printf("%d",min_of(a,NUMBER)); return(0); } 最も小さい数を出すようにしたいのですがうまくいきません。 どこがおかしいのでしょうか? 教えてくださいm(_ _ )m

  • 行列の積を関数を使って求める・・?

    2つの行列の行と列を入力し、積を計算するプログラムを関数を使って書きたいのですが、上手く行きません。どこをどのように直したらよいか教えてください!お願いします!! 以下が私が書いたプログラムです。 #include<stdio.h> #define NUMBER 10 int first(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; do{ printf("2つの行列の行と列を入力してください\n"); scanf("%d", &x1); scanf("%d", &x2); scanf("%d", &y1); scanf("%d", &y2); if(x1 != y2){ printf("行列の積は計算できません\n"); } }while(x1 != y2); printf("行列Aの要素を入力してください\n"); for(i=0; i<x1; i++){ for(j=0; j<x2; j++) scanf("%d", &a[i][j]); } printf("行列Bの要素を入力してください\n"); for(j=0; j<y1; j++){ for(k=0; k<y2; k++) scanf("%d", &b[j][k]); } } int second(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; for(i=0; i<x1; i++){ for(k=0; k<y2; k++){ for(j=0; j<x2; j++) c[i][k] = c[i][k] + a[i][j]*b[j][k]; } } for(i=0; i<x2; i++){ for(k=0; k<y2; k++) printf("%3d", c[i][k]); printf("\n"); } } int main(void) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; printf("行列の積を計算します\n %d\n", first(x1,x2,y1,y2,i,j,k)); printf("行列Aと行Bの積は\n %3d",second(x1,x2,y1,y2,i,j,k)); }

専門家に質問してみよう