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

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

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

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

Q&A

5回答

1951閲覧

学生のデータの並び替えと指定する学生を表示させたい。

Bulls

総合スコア4

C

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

0グッド

0クリップ

投稿2021/09/07 03:12

前提・実現したいこと

ここに質問の内容を詳しく書いてください。 卒業課題に躓いてしまったので、皆さんに教授していただきたく投稿させて頂きました。 問1. 学籍番号を入力して、個人の学籍番号、氏名、各科目点数、合計点、平均を表示。 問2. 昇順または降順にしたい列を選んで昇順にせよ。 私なりに調べましたが…qsortを使ったコードが上手く出力できないので、例を教えていただけないでしょうか。 列を指定するコードを入れるとごちゃごちゃになってしまったので、大まかな流れを書いていただけると幸いです。 よろしくお願いいたします。

該当のソースコード

C

1#include<stdio.h> 2 3int main(void) 4{ 5FILE * fp; 6int gakuseki = 0; 7char name[100]; 8int kokugo, math, english, sum; 9double ave; 10double sumk, summ, sume; 11 12if ((fp = fopen("class.dat", "r")) == NULL) /* オープン */ 13printf("\a\aファイル見つかりませんでした。\n"); 14else 15{ 16printf("\aファイルを開きます。\n"); 17printf("\a\n---全生徒のデータを表示---\n"); 18printf(" 学籍番号 | 氏 名 | 国 語 | 数 学 | 英 語 | 合計点 | 個人平均点\n"); 19 20while (fscanf(fp, "%d %s %d %d %d", &gakuseki, name, &kokugo, &math, &english) == 5) 21{ 22int sump = kokugo + math + english; 23printf("%11d | %-8s | %4d | %4d | %4d | %4d | %lf\n", gakuseki, name, kokugo, math, english, sump, (double)sump / 3); 24gakuseki++; 25sumk += kokugo; 26summ += math; 27sume += english; 28 29} 30 31printf(" 各科目平均 | - | %3.1f | %3.1f | %3.1f | - | -\n\n", sumk / gakuseki, summ / gakuseki, sume / gakuseki); 32 33 34fclose(fp); /* クローズ */ 35} 36 37int seach; 38printf("閲覧したい生徒の学籍番号を入力してください。: "); scanf("%d", &seach); 39seach = strstr(gakuseki, seach); 40printf(" 学籍番号 | 氏 名 | 国 語 | 数 学 | 英 語 | 合計点 | 個人平均点\n"); 41printf("%11d | %-8s | %4d | %4d | %4d \n", gakuseki, name, kokugo, math, english); 42 43return 0; 44}

コンパイル結果

閲覧したい生徒の学籍番号を入力しても、何も表示されませんでした。
エラーは出ないのに考えても分かりませんでした。
どなたかご教授よろしくお願いいたします。

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

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

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

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

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

tatsu99

2021/09/07 03:35

class.datの内容はどうなっていますか?
BeatStar

2021/09/07 03:40

せめて『インデント』ぐらいは入れましょうよ… Tabキーや半角スペースでやるアレです。 今のままでは読む気失せます。 特にfor文内にfor文があるとかのような入れ子の場合、相当読みづらい。 質問のコードもif文内にwhile文がある。 これでは面倒すぎる。 今の状態は、『ひらがなだけで表現し、かつ句読点もないし、顔文字もないような長文で、その長文が改行なしで表現されている感じ』です。 読む気失せます。 まずはインデントぐらいは入れましょう。
episteme

2021/09/07 03:42

卒業課題を丸投げとは大したもんだ。
BeatStar

2021/09/07 03:55

仕様が曖昧。 情報伏せてわかるわけないでしょ。
fana

2021/09/07 04:05

> 卒業課題 そういうものはさすがに自力でやらなきゃでしょ… (仮にここで答えをもらえたとして,提出先にここが発見されたら卒業できなくなる可能性…とか考えないのか?)
Bulls

2021/09/07 04:08

tatsu99さん class.datの内容を記載します。 1 Babe 44 81 63 2 Ruth 60 49 77 3 Lou 11 62 32 4 Gehrig 98 40 8 5 Joe 13 28 33 6 DiMaggio 56 60 63 7 Ian 78 69 73 8 Thorpe 38 48 0 9 Michael 5 88 96 10 Klim 61 4 36 11 Grant 41 54 10 12 Hackett 47 70 90 13 Kieren 79 26 62 14 Perkins 37 11 82 15 Mark 19 31 23 16 McGwire 55 52 87 17 Sammy 21 93 63 18 Sosa 38 13 79 19 Jim 48 45 41 20 Abott 77 61 67 21 Jordan 94 50 19 22 Scottie 7 87 14 23 Pippen 1 40 24 24 Dennis 20 9 86 25 Rodman 5 32 14 26 Pedro 85 95 25 27 Martinez 67 84 46 28 Yurisbel 75 34 29 29 Gracial 18 93 4 30 Moinelo 28 82 75 宜しくお願い致します。
bboydaisuke

2021/09/07 05:38

質問の中に含めるべきものを「質問の追記依頼」の所に書く質問者のセンスがすごいと思いました。
bboydaisuke

2021/09/07 05:41 編集

「卒業課題」ってことは学校に行ってるんだから、先生とか学生の仲間に聞けばいいのに。これから卒業するってことは何年も行っているんだから、一人も知っている人がいないってことはないでしょう。
dodox86

2021/09/07 06:56

なぜこう、できていない・理解できていない複数のことを同時に片付けようとするのか。ひとつずつ理解して順番に片付けましょうよ。
WoodenHamlet

2021/09/08 04:04

卒業するべきでない人間は卒業するべきではない(トートロジー)
guest

回答5

0

問1. 学籍番号を入力して、個人の学籍番号、氏名、各科目点数、合計点、平均を表示。
問2. 昇順または降順にしたい列を選んで昇順にせよ。(解釈不能だが原文ママ)

これを実現するには何らかの**"表(table)”が必要だが、コード中にそれが見当たらない**。
それが卒業課題に躓いてしまった主因(と断言する)。

投稿2021/09/07 03:33

編集2021/09/07 03:45
episteme

総合スコア16612

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

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

0

恐らく問1を解き始める段階にも到達していないのではないでしょうか
ファイルを読んで中身を表示しようとしているだろう部分ですでに崩壊の兆しが見受けられます。
コンパイルもしてない時点での所見ですが、

  • sumk, summ, sume が初期化されていないため、表示される各科目平均が多分でたらめな値になる
  • CSVの中身がわからないので何とも言えないが、平均を出すときの計算が「(上記のでたらめな)合算値/最後に読んだ人間の学籍番号+1」になるので、でたらめな値になる。点数リストが学籍番号順で並んでいて、かつ0始まりなら大丈夫なのか?
  • ファイルが読めなかった時でも問1の学籍番号を訪ねる処理に入ってしまう

投稿2021/09/08 08:14

WoodenHamlet

総合スコア306

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

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

0

「必ずqsortを使え」という隠された条件が存在するのでもないならば,
わざわざよくわからんqsortを使う義理も無ければ義務もないのではあるまいか.
qsortがわからんなら他の方法を採れば良い.

e.g. バケットソート:

問2. 昇順または降順にしたい列を選んで昇順にせよ。

という話において「選べる列の個数」がn個であれば,n次元ボクセル空間に各生徒をマッピングすればよい.
これで実質「ソート」の作業は完了だ.
あとは選ばれた列に従ってボクセル空間を走査し,生徒を拾い集めて表示するだけだ.

投稿2021/09/08 03:38

fana

総合スコア11996

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

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

0

一番の問題点は、読み込んだ生徒の数分のデータを格納する変数を定義していないことです。
int kokugo, math, english, sum; の定義はでは、一人分のデータだけしか格納できません。
昇順、又は降順に並べ替えるためには、全員分のデータを確保できるように変数を配列で定義する必要があります。
以下のようにしてください。
提示したソースでは、①氏名を昇順に並べ替え、②国語の点数で昇順に並べ替えを行っています。
他の科目での並び替え、及び、降順での並び替えは、提示されたソースを元にあなたの方でトライしてください。
トライした結果、うまくいかなければ、再度質問してください。
尚、100人分まで格納できますが、それを超えた場合のチェックは行っていません。必要であれば、あなたが修正してください。

C

1#include<string.h> 2#include<stdio.h> 3#include<stdlib.h> 4struct person { 5 int gakuseki; //学籍番号 6 char name[100]; //氏名 7 int kokugo; //国語 8 int math; //数学 9 int english; //英語 10 int sum; //合計 11}; 12int comp_name(const void *e1,const void *e2); 13int comp_kokugo(const void *e1,const void *e2); 14 15 16int main(void) 17{ 18 FILE *fp; 19 int gaku_count = 0; //生徒数 20 int gakuseki; 21 char name[100]; 22 int kokugo, math, english, sum; 23 double ave; 24 double sumk, summ, sume; 25 struct person all[100]; //生徒100人分 26 int i; 27 if ((fp = fopen("class.dat", "r")) == NULL) /* オープン */ 28 printf("\a\aファイル見つかりませんでした。\n"); 29 else { 30 printf("\aファイルを開きます。\n"); 31 printf("\a\n---全生徒のデータを表示---\n"); 32 printf 33 (" 学籍番号 | 氏 名 | 国 語 | 数 学 | 英 語 | 合計点 | 個人平均点\n"); 34 35 while (fscanf 36 (fp, "%d %s %d %d %d", &gakuseki, name, &kokugo, &math, 37 &english) == 5) { 38 int sump = kokugo + math + english; 39 printf 40 ("%11d | %-8s | %4d | %4d | %4d | %4d | %lf\n", 41 gakuseki, name, kokugo, math, english, sump, 42 (double) sump / 3); 43 sumk += kokugo; 44 summ += math; 45 sume += english; 46 all[gaku_count].gakuseki = gakuseki; 47 strcpy(all[gaku_count].name,name); 48 all[gaku_count].kokugo = kokugo; 49 all[gaku_count].math = math; 50 all[gaku_count].english = english; 51 all[gaku_count].sum = sump; 52 gaku_count++; 53 } 54 55 printf 56 (" 各科目平均 | - | %3.1f | %3.1f | %3.1f | - | -\n\n", 57 sumk / gakuseki, summ / gakuseki, sume / gakuseki); 58 59 60 fclose(fp); /* クローズ */ 61 } 62 63 int seach; 64 int fx = -1; 65 printf("閲覧したい生徒の学籍番号を入力してください。: "); 66 scanf("%d", &seach); 67 for (i = 0; i < gaku_count; i++){ 68 if (seach == all[i].gakuseki){ 69 fx = i; 70 break; 71 } 72 } 73 if (fx == -1){ 74 printf("該当者なし\n"); 75 }else{ 76 printf 77 (" 学籍番号 | 氏 名 | 国 語 | 数 学 | 英 語 | 合計点 | 個人平均点\n"); 78 printf("%11d | %-8s | %4d | %4d | %4d | %4d | %lf \n", all[fx].gakuseki, all[fx].name, 79 all[fx].kokugo, all[fx].math, all[fx].english, all[fx].sum, (double)all[fx].sum / 3.0); 80 } 81 82 int column; 83 printf("昇順にしたい列を入力してください。: "); 84 scanf("%d", &column); 85 switch (column){ 86 case 1: //学籍番号 87 break; 88 case 2: //氏名 89 qsort(all,gaku_count,sizeof(struct person),comp_name); 90 break; 91 case 3: //国語 92 qsort(all,gaku_count,sizeof(struct person),comp_kokugo); 93 break; 94 //以下省略 95 default: 96 break; 97 } 98 printf 99 (" 学籍番号 | 氏 名 | 国 語 | 数 学 | 英 語 | 合計点 | 個人平均点\n"); 100 for (i = 0; i < gaku_count;i++){ 101 printf("%11d | %-8s | %4d | %4d | %4d | %4d | %lf \n", all[i].gakuseki, all[i].name, 102 all[i].kokugo, all[i].math, all[i].english, all[i].sum, (double)all[i].sum / 3.0); 103 } 104 return 0; 105} 106int comp_name(const void *e1,const void *e2) 107{ 108 struct person *p1 = e1; 109 struct person *p2 = e2; 110 int ret; 111 ret = strcmp(p1->name,p2->name); 112 return ret; 113} 114int comp_kokugo(const void *e1,const void *e2) 115{ 116 struct person *p1 = e1; 117 struct person *p2 = e2; 118 int ret; 119 ret = p1->kokugo - p2->kokugo; 120 return ret; 121} 122

投稿2021/09/08 02:58

tatsu99

総合スコア5493

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

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

0

qsortを使ったコードが上手く出力できない

ということなので、qsortの使い方のサンプルだけ提示します。
こちらを参考に、各データを構造体にして、それを並べ替えるようにしました。

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5// 並べ替え対象の構造体 6struct score_data 7{ 8 int id; 9 char name[100]; 10 int score; 11}; 12 13// scoreを比較する関数 14int compare_score_asc(const void *a, const void *b) 15{ 16 return ((struct score_data *)a)->score - ((struct score_data *)b)->score; 17} 18 19// データの出力 20void print_datas(struct score_data *datas, int length) 21{ 22 int loop; 23 24 for (loop = 0; loop < length; loop++) 25 { 26 printf("%11d | %-8s | %4d \n", 27 datas[loop].id, 28 datas[loop].name, 29 datas[loop].score); 30 } 31 printf("----------\n"); 32} 33 34int main(void){ 35 struct score_data datas[3]; 36 37 // データの入力 38 datas[0].id = 0; 39 strcpy(datas[0].name, "sato"); 40 datas[0].score = 50; 41 42 datas[1].id = 1; 43 strcpy(datas[1].name, "goto"); 44 datas[1].score = 100; 45 46 datas[2].id = 2; 47 strcpy(datas[2].name, "takeda"); 48 datas[2].score = 0; 49 50 // 最初の状態を出力 51 print_datas(datas, 3); 52 53 // 並べ替え 54 qsort(datas, 3, sizeof(struct score_data), compare_score_asc); 55 56 // 出力 57 print_datas(datas, 3); 58 59 return 0; 60}

なお、コードにはあえて記載していませんが、文字列同士の比較はstrcmp()を使うのが楽です。

投稿2021/09/07 04:35

fiveHundred

総合スコア10152

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

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

fiveHundred

2021/09/07 04:52

っと回答したけれども、問1.の表示すら出来ていない状況なのか…。 これだとqsortの使い方以前の問題ですね。 やり方としては、どこかに全てのデータを保持しておき、入力されたらそれらのデータの中から同じ学籍番号のものを出力すればいいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問