質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

3回答

500閲覧

選択ソートがうまくできません。C言語です。

yuusuke123

総合スコア10

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/10/14 04:42

前提・実現したいこと

それぞれの学生の点数の合計点の高い順に、それに従って、番号、名前、素点も並び替えるプログラムを作っています。番号、名前、素点の英語、合計点は正しく並び替えることができましたが、数学と物理が並び替えることができません。どのようにプログラムを改善すればいいのでしょうか?教えてください。

発生している問題・エラーメッセージ

英語のみがソートされ、他の科目はそのままで表示されてしまいます。

該当のソースコード

#include<stdio.h> #include<string.h> struct slist { int num; /* 番号 */ char name[20]; /* 名前 */ int ten[6]; /* 各科目の点数(3科目) */ int total; /* 合計点 */ }; int main(void) { /*変数宣言と配列の初期値設定*/ int i, j, jmax, totalmax, nummax; int N = 7, M = 3, K = 6; /* N:学生数, M:科目数 K:項目数*/ char a[20]; char b[6]; struct slist seiseki[7] = { { 1, "Ito", { 65, 55, 80 }, 0 }, { 2, "Kato", { 30, 40, 50 }, 0 }, { 3, "Tanaka", { 65, 85, 100 }, 0 }, { 4, "Suzuki", { 85, 90, 65 }, 0 }, { 5, "Yamada", { 20, 50, 80 }, 0 }, { 6, "Takada", { 90, 30, 40 }, 0 }, { 7, "Sato", { 50, 70, 55 }, 0 } }; char hyodai[6][7] = { "No.", "Name", "Eigo", "Sugaku", "Buturi", "Total" }; /*表題の表示*/ printf("------------------------------------------------\n"); printf(" Original Data\n"); printf("------------------------------------------------\n"); for (i = 0; i < K; i++) { printf("%8s", hyodai[i]); }; printf("\n"); for (i = 0; i < N; i++) { printf("%8d%8s", seiseki[i].num, seiseki[i].name); for (j = 0; j < M; j++) { printf("%8d", seiseki[i].ten[j]); seiseki[i].total += seiseki[i].ten[j]; } printf("%8d\n", seiseki[i].total); } for (i = 0; i < N - 1; i++) { totalmax = seiseki[i].total; jmax = i; /* 最大値を求める*/ for (j = i + 1; j < N; j++) { if (totalmax < seiseki[j].total) { jmax = j; totalmax = seiseki[j].total; } nummax = seiseki[jmax].num; strcpy(a,seiseki[jmax].name); memcpy(b,seiseki[jmax].ten,sizeof(5)); } /* 最大値(jmax番目)のデータとi番目のデータを交換*/ seiseki[jmax].total = seiseki[i].total; seiseki[i].total = totalmax; seiseki[jmax].num = seiseki[i].num; seiseki[i].num = nummax; strcpy(seiseki[jmax].name,seiseki[i].name); strcpy(seiseki[i].name,a); memcpy(seiseki[jmax].ten,seiseki[i].ten,sizeof(5)); memcpy(seiseki[i].ten,b,sizeof(5)); } /*並ぎ替え後の合計点の表示 */ printf("--------------------------\n"); printf("並び替えデータ\n"); printf("--------------------------\n"); for (i = 0; i < K; i++) { printf("%8s", hyodai[i]); }; printf("\n"); for (j = 0; j < N; j++) { printf("%8d%8s%8d%8d%8d%8d\n", seiseki[j].num, seiseki[j].name,seiseki[j].ten[0],seiseki[j].ten[1],seiseki[j].ten[2], seiseki[j].total); } return (0); }

試したこと

英語、物理、数学をそれぞれseiseki[j].ten[1],seiseki[j].ten[2],seiseki[j].ten[3]として3つ別々に並び替えようとしましたが、エラーになってしまいました。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

処理を関数に分割して、 main() がスッキリとなるようにしてみました。

c

1#include<stdio.h> 2#include<string.h> 3 4struct slist { 5 int num; // 生徒番号 */ 6 char name[64]; // 名前 7 int ten[6]; // 各科目の点数 8 int total; // 合計点 9}; 10const int NUM_TEN = 3; // 先頭の3科目だけを今は使う 11 12void show_data(struct slist* data) { 13 printf("%8d%8s", data->num, data->name); 14 for (int j = 0; j < NUM_TEN; j++) { 15 printf("%8d", data->ten[j]); 16 } 17 printf("%8d\n", data->total); 18} 19 20void copy_data(struct slist* to_seiseki, struct slist* from_seiseki) { 21 to_seiseki->num = from_seiseki->num; 22 strcpy(to_seiseki->name, from_seiseki->name); 23 for (int i = 0; i < NUM_TEN; i++) { 24 to_seiseki->ten[i] = from_seiseki->ten[i]; 25 } 26 to_seiseki->total = from_seiseki->total; 27} 28 29void swap_data(struct slist* data_1, struct slist* data_2) { 30 struct slist tmp; 31 copy_data(&tmp, data_1); 32 copy_data(data_1, data_2); 33 copy_data(data_2, &tmp); 34} 35 36void calc_total_all(struct slist* seiseki, int num_data) { 37 for (int i = 0; i < num_data; i++) { 38 seiseki[i].total = 0; 39 for (int j = 0; j < NUM_TEN; j++) { 40 seiseki[i].total += seiseki[i].ten[j]; 41 } 42 } 43} 44 45void show_data_all(char* title, struct slist* seiseki, int num_data, char** hyodai, int num_col) { 46 // 表題の表示 47 printf("------------------------------------------------\n"); 48 printf("%s\n", title); 49 printf("------------------------------------------------\n"); 50 if (hyodai != NULL) { 51 for (int i = 0; i < num_col; i++) { 52 printf("%8s", hyodai[i]); 53 } 54 printf("\n"); 55 } 56 57 for (int i = 0; i < num_data; i++) { 58 show_data(&seiseki[i]); 59 } 60} 61 62void sort_data_all(struct slist* seiseki, int num_data) { 63 int totalmax = -1; 64 for (int i = 0; i < num_data - 1; i++) { 65 totalmax = seiseki[i].total; 66 int jmax = i; 67 68 // total の最大値を求める 69 for (int j = i + 1; j < num_data; j++) { 70 if (totalmax < seiseki[j].total) { 71 jmax = j; 72 totalmax = seiseki[j].total; 73 } 74 } 75 76 // 最大値(jmax番目)のデータとi番目のデータを交換 77 if (i != jmax) { 78 swap_data(&seiseki[i], &seiseki[jmax]); 79 } 80 } 81} 82 83int main(void) { 84 char* hyodai[] = { "No.", "Name", "Eigo", "Sugaku", "Buturi", "Total" }; 85 struct slist seiseki[] = 86 { 87 // { 1, "AAA", { 10, 10, 10}, 0 }, 88 // { 2, "BBB", {30, 30, 30 }, 0 }, 89 // { 3, "CCC", { 20, 20, 20 }, 0 }, 90 91 { 1, "Ito", { 65, 55, 80 }, 0 }, 92 { 2, "Kato", {30, 40, 50 }, 0 }, 93 { 3, "Tanaka", { 65, 85, 100 }, 0 }, 94 { 4, "Suzuki", { 85, 90, 65 }, 0 }, 95 { 5, "Yamada", { 20, 50, 80 }, 0 }, 96 { 6, "Takada", { 90, 30, 40 }, 0 }, 97 { 7, "Sato", { 50, 70, 55 }, 0 } 98 }; 99 const int K = sizeof(hyodai) / sizeof(char*); // 科目数 + 3 100 const int N = sizeof(seiseki) / sizeof(struct slist); // 学生数 101 102 calc_total_all(seiseki, N); 103 show_data_all("Original Data", seiseki, N, hyodai, K); 104 sort_data_all(seiseki, N); 105 show_data_all("並び替え後データ", seiseki, N, NULL, K); 106 return (0); 107}

実行例
イメージ説明

投稿2018/10/14 11:19

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

修正しました。修正箇所は//MODとコメントしています。
char b[6];は
int b[6];でなければいけません。(int型のデータを6個格納するから)
memcpyですが、
sizeof(5)は、意味不明です。
5バイトを転送したいなら、memcpy(x,y,5)のように直接5を記述します。
今回は、送り元のデータのサイズを記述しました。
memcpy(x,y,sizeof(y))のようにしました。
ここで転送するのは、全てint b[6]のサイズなので、全て sizeof(b)
としても構いません。

C

1#include<stdio.h> 2#include<string.h> 3 4struct slist { 5 int num; /* 番号 */ 6 char name[20]; /* 名前 */ 7 int ten[6]; /* 各科目の点数(3科目) */ 8 int total; /* 合計点 */ 9}; 10 11int main(void) { 12 /*変数宣言と配列の初期値設定*/ 13 int i, j, jmax, totalmax, nummax; 14 int N = 7, M = 3, K = 6; /* N:学生数, M:科目数 K:項目数*/ 15 char a[20]; 16 //char b[6]; 17 int b[6]; //MOD 18 19 struct slist seiseki[7] = { { 1, "Ito", { 65, 55, 80 }, 0 }, { 2, "Kato", { 20 30, 40, 50 }, 0 }, { 3, "Tanaka", { 65, 85, 100 }, 0 }, { 4, 21 "Suzuki", { 85, 90, 65 }, 0 }, { 5, "Yamada", { 20, 50, 80 }, 0 }, { 22 6, "Takada", { 90, 30, 40 }, 0 }, { 7, "Sato", { 50, 70, 55 }, 0 } }; 23 char hyodai[6][7] = { "No.", "Name", "Eigo", "Sugaku", "Buturi", "Total" }; 24 25 /*表題の表示*/ 26 printf("------------------------------------------------\n"); 27 printf(" Original Data\n"); 28 printf("------------------------------------------------\n"); 29 for (i = 0; i < K; i++) { 30 printf("%8s", hyodai[i]); 31 }; 32 printf("\n"); 33 34 for (i = 0; i < N; i++) { 35 printf("%8d%8s", seiseki[i].num, seiseki[i].name); 36 37 for (j = 0; j < M; j++) { 38 printf("%8d", seiseki[i].ten[j]); 39 seiseki[i].total += seiseki[i].ten[j]; 40 } 41 printf("%8d\n", seiseki[i].total); 42 } 43 44 for (i = 0; i < N - 1; i++) { 45 46 totalmax = seiseki[i].total; 47 jmax = i; 48 49 /* 最大値を求める*/ 50 for (j = i + 1; j < N; j++) { 51 52 if (totalmax < seiseki[j].total) { 53 jmax = j; 54 totalmax = seiseki[j].total; 55 } 56 nummax = seiseki[jmax].num; 57 strcpy(a,seiseki[jmax].name); 58 memcpy(b,seiseki[jmax].ten,sizeof(seiseki[jmax].ten)); //MOD 59 60 } 61 62 63 /* 最大値(jmax番目)のデータとi番目のデータを交換*/ 64 seiseki[jmax].total = seiseki[i].total; 65 seiseki[i].total = totalmax; 66 seiseki[jmax].num = seiseki[i].num; 67 seiseki[i].num = nummax; 68 strcpy(seiseki[jmax].name,seiseki[i].name); 69 strcpy(seiseki[i].name,a); 70 71 memcpy(seiseki[jmax].ten,seiseki[i].ten,sizeof(seiseki[i].ten)); //MOD 72 memcpy(seiseki[i].ten,b,sizeof(b)); //MOD 73 74 } 75 /*並ぎ替え後の合計点の表示 */ 76 printf("--------------------------\n"); 77 printf("並び替えデータ\n"); 78 printf("--------------------------\n"); 79 for (i = 0; i < K; i++) { 80 printf("%8s", hyodai[i]); 81 }; 82 printf("\n"); 83 84 for (j = 0; j < N; j++) { 85 printf("%8d%8s%8d%8d%8d%8d\n", seiseki[j].num, seiseki[j].name,seiseki[j].ten[0],seiseki[j].ten[1],seiseki[j].ten[2], seiseki[j].total); 86 } 87 88 return (0); 89} 90

投稿2018/10/14 07:06

tatsu99

総合スコア5438

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

char b[6];

intを3つ格納するには小さすぎます。
int b[3];にすべきでしょう。

memcpy(b,seiseki[jmax].ten,sizeof(5));

どこからsizeof(5)が出てきたのでしょうか?

c

1memcpy(b,seiseki[jmax].ten,sizeof(int)*3);

もしくは

C

1memcpy(b,seiseki[jmax].ten,sizeof(seiseki[jmax].ten));

にしましょう。

投稿2018/10/14 07:03

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問