構造体(姓、身長、体重、年齢)を作成して身長で昇順ソートする。
教えて下さい。今は下のようになっています。
#include <stdio.h>
typedef struct Student{
char sur[100];
double hei,wei;
int age;
}Student;
int main(void)
{
Student stu[5],tmp;
int i,j;
int n,m;
printf("五人分のデータを入力してください\n");
for(i = 1;i <= 5;i++){
printf("%d人目姓、身長、体重、年齢をスペース区切りで入力後Enter\n",i);
scanf("%s %lf %lf %d",&stu[i].sur,&stu[i].hei,&stu[i].wei,&stu[i].age);
}
printf("ソートのキー (1:身長 , 2:体重) : ");
scanf("%d",&n);
printf("\n\n");
switch(n){
case 1:
for(i = 1;i <= 5;i++){
for(j = i + 1;j <= 5 ;j++){
if(stu[i].hei > stu[j].hei){
tmp = stu[i];
stu[i] = stu[j];
stu[j] = tmp;
}
}
}
for(i =1;i <= 5;i++){
printf("%s %.1lf %.1lf %d\n",stu[i].sur,stu[i].hei,stu[i].wei,stu[i].age);
}
case 2:
for(i = 1;i <= 5;i++){
for(j = i + 1;j <= 5 ;j++){
if(stu[i].wei > stu[j].wei){
tmp = stu[i];
stu[i] = stu[j];
stu[j] = tmp;
}
}
}
for(i =1;i <= 5;i++){
printf("%s %.1lf %.1lf %d\n",stu[i].sur,stu[i].hei,stu[i].wei,stu[i].age);
}
}
return 0;
}
No.2ベストアンサー
- 回答日時:
問題点1:配列の添え字は0から開始します。
従って、stu[5]の配列は、0~4が有効な添え字です。
OKの範囲はstu[0]~stu[4]です。
あなたの場合、i=5でstu[i]を参照するとき、範囲外のアクセスの為、
プログラムが暴走します。
それを踏まえて、
for(i = 1;i <= 5;i++){
printf("%d人目姓、身長、体重、年齢をスペース区切りで入力後Enter\n",i);
scanf("%s %lf %lf %d",&stu[i].sur,&stu[i].hei,&stu[i].wei,&stu[i].age);
}
を修正すると
for (i = 0; i < 5; i++) {
printf("%d人目姓、身長、体重、年齢をスペース区切りで入力後Enter\n",
i+1);
scanf("%s %lf %lf %d", &stu[i].sur, &stu[i].hei, &stu[i].wei,
&stu[i].age);
}
になります。
他も、同様に修正してください。
問題点2:
switch case文で
case1 :の最後にbreak;を入れてください。
そうしないと、case 2:の方も実行してしまいます。
問題点3:
問題点というほどではありませんが、#1の方も言っているように、
ソート結果を印字する処理は、switch caseが終わってからにすると、
1っ箇所で済みます。
No.3
- 回答日時:
例えばこんなカンジ。
/* ここから */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Student {
char sur[100];
double hei, wei;
int age;
} Student;
int cmp_hei(const void *p, const void *q) {
return ((Student*)p)->hei - ((Student*)q)->hei;
}
int cmp_wei(const void *p, const void *q) {
return ((Student*)p)->wei - ((Student*)q)->wei;
}
int main(void) {
Student stu[5];
char tmp[128];
int n;
puts("五人分のデータを入力してください\n");
for (int i = 0; i < 5; i++) {
printf("%d人目姓、身長、体重、年齢をスペース区切りで入力後Enter\n", i+1);
scanf("%127[^\n]%*c", tmp);
strcpy(stu[i].sur, strtok(tmp, " "));
stu[i].hei = strtod(strtok(NULL, " "), NULL);
stu[i].wei = strtod(strtok(NULL, " "), NULL);
stu[i].age = strtol(strtok(NULL, " "), NULL, 10);
}
printf("ソートのキー(1:身長, 2:体重): ");
scanf("%1[^\n]%*c", tmp);
n = strtol(tmp, NULL, 10);
printf("\n\n");
switch(n) {
case 1:
qsort(stu, 5, sizeof(Student), cmp_hei);
break;
case 2:
qsort(stu, 5, sizeof(Student), cmp_wei);
break;
}
for (int i = 0; i < 5; i++) {
printf("%s %.1lf %.1lf %d\n", stu[i].sur, stu[i].hei, stu[i].wei, stu[i].age);
}
return EXIT_SUCCESS;
}
/* ここまで */
昇順・降順のアルゴリズム考えるよりも、C言語の標準ライブラリ(stdlib.h)に入ってるqsort関数を使った方が早い。
qsort:
https://www.cc.kyoto-su.ac.jp/~yamada/ap/qsort.h …
No.1
- 回答日時:
細かくコードを読む気はないですが…
>Student stu[5],tmp;
で、確保した配列で添え字に指定可能に範囲はどこからどこまででしょう?
その上で…
>for(i = 1;i <= 5;i++){
は安全な範囲に入ると思いますか?
さらに…
>for(j = i + 1;j <= 5 ;j++){
でiが5の時にループが回ると思いますか?
# まぁソートが正常に完了しているのならば最後のは不要なのでループ回らなくてもいいのですが。
switch()~case文でbreakしなかったらどうなると思いますか?
# 結果の表示は一緒なのですからswitchから抜けた後の表示でいいんじゃないですかね?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語(構造体) 3 2022/07/05 20:08
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# c言語でユーザ関数を利用して複素数のべき乗と絶対値の数列を計算するプログラムが作りたいです。 3 2023/01/29 22:13
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# LU分解法のピボッティングについて(C言語/gcc-9) 3 2022/07/11 23:10
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- C言語・C++・C# LU分解法のピボット選択機能実装について(C言語・gcc-9) 1 2022/07/22 15:20
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語での、年複利の計算方法...
-
C言語の勉強しています。すみま...
-
printf で二進表示を行いたい。
-
8人分のテストの点数を入力し、...
-
プログラム(C言語)
-
コーディング
-
【C言語教えてください】sin波...
-
C言語 プログラミング
-
switch分のケースを範囲数?に...
-
台形の面積を求めるプログラム
-
ブラックジャック
-
三角形の判別
-
10進数を2進数に変換するには・...
-
覆面算 C
-
改行について 1行に何個かづ...
-
困ってます!Cプログラミングに...
-
srand(time(NULL))の使い方
-
パスカルの三角形についてのCプ...
-
printfの変換仕様について
-
LU分解法のピボッティングにつ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
10個出力で改行したいのですが...
-
printf で二進表示を行いたい。
-
【C言語教えてください】sin波...
-
strcmp
-
コンパイルエラーについて
-
c言語でAからZまでを表示する...
-
コマンドラインに出力した文字...
-
cshの文字列操作(0埋め)
-
4の倍数を論理演算で表す。。
-
C言語 プログラミング
-
8人分のテストの点数を入力し、...
-
%P と %X の違い
-
C言語での、年複利の計算方法...
-
printf( " %2d", p * q );
-
hit&bolwのプログラミングがで...
-
scanfに文字が入力されたときに...
-
error C2143: 構文エラー : ';'...
-
printfの出力内の文字をdefine...
-
テキストカーソル位置の取得
-
unsigned int型について
おすすめ情報