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

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

ただいまの
回答率

90.32%

  • C

    3997questions

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

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

受付中

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 155

yuusuke123

score 0

 前提・実現したいこと

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

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

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

 該当のソースコード

#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/ツールのバージョンなど)

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+1

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

#include<stdio.h>
#include<string.h>

struct slist {
  int num; // 生徒番号 */
  char name[64]; // 名前
  int ten[6]; // 各科目の点数
  int total; // 合計点
};
const int NUM_TEN = 3;  // 先頭の3科目だけを今は使う

void show_data(struct slist* data) {
  printf("%8d%8s", data->num, data->name);
  for (int j = 0; j < NUM_TEN; j++) {
    printf("%8d", data->ten[j]);
  }
  printf("%8d\n", data->total);
}

void copy_data(struct slist* to_seiseki, struct slist* from_seiseki) {
  to_seiseki->num = from_seiseki->num;
  strcpy(to_seiseki->name, from_seiseki->name);
  for (int i = 0; i < NUM_TEN; i++) {
    to_seiseki->ten[i] = from_seiseki->ten[i];
  }
  to_seiseki->total = from_seiseki->total;
}

void swap_data(struct slist* data_1, struct slist* data_2) {
  struct slist tmp;
  copy_data(&tmp, data_1);
  copy_data(data_1, data_2);
  copy_data(data_2, &tmp);
}

void calc_total_all(struct slist* seiseki, int num_data) {
  for (int i = 0; i < num_data; i++) {
    seiseki[i].total = 0;
    for (int j = 0; j < NUM_TEN; j++) {
      seiseki[i].total += seiseki[i].ten[j];
    }
  }
}

void show_data_all(char* title, struct slist* seiseki, int num_data, char** hyodai, int num_col) {
  // 表題の表示
  printf("------------------------------------------------\n");
  printf("%s\n", title);
  printf("------------------------------------------------\n");
  if (hyodai != NULL) {
    for (int i = 0; i < num_col; i++) {
      printf("%8s", hyodai[i]);
    }
    printf("\n");
  }

  for (int i = 0; i < num_data; i++) {
    show_data(&seiseki[i]);
  }
}

void sort_data_all(struct slist* seiseki, int num_data) {
  int totalmax = -1;
  for (int i = 0; i < num_data - 1; i++) {
    totalmax = seiseki[i].total;
    int jmax = i;

    // total の最大値を求める
    for (int j = i + 1; j < num_data; j++) {
      if (totalmax < seiseki[j].total) {
    jmax = j;
    totalmax = seiseki[j].total;
      }
    }

    // 最大値(jmax番目)のデータとi番目のデータを交換
    if (i != jmax) {
      swap_data(&seiseki[i], &seiseki[jmax]);
    }
  }
}

int main(void) {
  char*  hyodai[] = { "No.", "Name", "Eigo", "Sugaku", "Buturi", "Total" };
  struct slist seiseki[] =
    {
     // { 1, "AAA", { 10, 10, 10}, 0 },
     // { 2, "BBB", {30, 30, 30 }, 0 },
     // { 3, "CCC", { 20, 20, 20 }, 0 },

     { 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 }
    };
  const int K = sizeof(hyodai) / sizeof(char*); // 科目数 + 3
  const int N = sizeof(seiseki) / sizeof(struct slist); // 学生数

  calc_total_all(seiseki, N);
  show_data_all("Original Data", seiseki, N, hyodai, K);
  sort_data_all(seiseki, N);
  show_data_all("並び替え後データ", seiseki, N, NULL, K);
  return (0);
}

実行例
イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

    char b[6];

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

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

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

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


もしくは

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


にしましょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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)
としても構いません。

#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];
    int    b[6];    //MOD

    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(seiseki[jmax].ten));  //MOD

        }


        /* 最大値(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(seiseki[i].ten));    //MOD
        memcpy(seiseki[i].ten,b,sizeof(b)); //MOD

    }
    /*並ぎ替え後の合計点の表示 */
    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);
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • C

    3997questions

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