合計 昨日 今日

ファイルからデータを読み込んで並べ替えたいです

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: すきさほんきさ
[URL]
Date: 2018年1月13日(土) 17:39
No: 1
(OFFLINE)

 ファイルからデータを読み込んで並べ替えたいです

ファイル"J_LEAGUE.txt"
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
浦和レッズ 62 52 32
徳島ヴォルティス 14 16 74
アルビレックス新潟 44 30 36
横浜F・マリノス 51 37 29
柏レイソル 60 48 40
大宮アルディージャ 35 44 60
セレッソ大阪 31 36 48
川崎フロンターレ 55 56 43
鹿島アントラーズ 60 64 39
サンフレッチェ広島 50 44 37
FC東京 48 47 33
ガンバ大阪 63 59 31
ヴァンフォーレ甲府 41 27 31
ベガルタ仙台 38 35 50
名古屋グランパス 48 47 48
サガン鳥栖 60 41 33
清水エスパルス 36 42 60
ヴィッセル神戸 45 49 50
//////////////////////////////////////////////////////////////////////
からデータを読み込んで、勝ち点順に並べ替え、勝ち点が同じ場合は得失点差で並べ替えをしたいです。
とりあえず、データをすべて読み込んで配列に保存するプログラムを書きたいのですが、警告がでてうまく実行できません。
1>c:\users\keisuke\documents\visual studio 2017\projects\3.c\j1633升田圭亮3.c(26): warning C4477: 'fscanf_s' : 書式文字列 '%s' には、型 'unsigned int' の引数が必要ですが、可変個引数 2 は型 'int *' です
1>c:\users\keisuke\documents\visual studio 2017\projects\3.c\3.c(26): note: この引数はバッファー サイズとして使用されます
1>c:\users\keisuke\documents\visual studio 2017\projects\3.c\3.c(26): warning C4473: 'fscanf_s': 書式文字列として渡された引数が不足しています
1>c:\users\keisuke\documents\visual studio 2017\projects\j13.c\3.c(26): note: プレースホルダーとそのパラメーターには 5 の可変個引数が必要ですが、4 が指定されています。
1>c:\users\keisuke\documents\visual studio 2017\projects\3.c\3.c(26): note: 不足している可変個引数 5 が書式文字列 '%d' に必要です

何がいけないのでしょうか。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
 
struct LeagueData {
    char team[20]; //チーム名
    int points;    //勝ち点
    int g_for;     //得点
    int g_against; //失点
    int g_diff;    //得失点差
} L_Data[18];
//int Compare(const void*d1, const void*d2) {
    //return ((struct Leaguedata*)d2)-> - ((struct Car *)p2)->num
//}
void DispTable(struct LeagueData *L_Data, int n)
{
 
}
int main() {
    int i;
    FILE*fp;
    fopen_s(&fp, "J_LEAGUE.txt", "r");
    if (fp == NULL) {
        printf_s("ファイルを開けませんでした.\n");
        return -1;
    }
    for (i = 0; i < 18; i++) {
        fscanf_s(fp,"%s %d %d %d ", &L_Data[i].team, &L_Data[i].points, &L_Data[i].g_for, &L_Data[i].g_against);
        L_Data[i].g_diff = L_Data[i].g_for - L_Data[i].g_against;
        printf_s("%s %d %d %d %d \n", L_Data[i].team, L_Data[i].points, L_Data[i].g_for, L_Data[i].g_against, L_Data->g_diff);
    }
    fclose(fp);
    return 0;
}

Name: みけCAT
[URL]
伝説なるハッカー(690,560 ポイント)
Date: 2018年1月13日(土) 19:49
No: 2
(ONLINE)

 Re: ファイルからデータを読み込んで並べ替えたいです

メッセージにある通り、fscanf_の引数で指定しないといけないバッファサイズを指定していないのがいけません。
さらに、fscanf_sの引数でL_Data[i].teamではなく&L_Data[i].teamを使ってしまっているのも型が異なってしまい、よくなさそうですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Name: すきさほんきさ
[URL]
Date: 2018年1月14日(日) 20:18
No: 3
(OFFLINE)

 Re: ファイルからデータを読み込んで並べ替えたいです

ソートのやり方が分かりません。

やりたいこと
構造体配列とチーム数を受け取り,勝ち点の多い順にチームデータを表⽰ する関数void DispTable( struct LeagueData *, int )を定義
• qsort関数はDispTable関数内で呼び出す。⽐較関数も⾃分で定義
main関数で構造体LeagueData型の配列(要素数20)を宣⾔し,ファイル からデータを読み込んで構造体配列の各メンバーに保存 (得失点差は計算してメンバーに保存)
全データ読み込み後,DispTable関数を1度だけ呼び出し,順位表を表⽰

いまできているのはファイルからデータを読み込むところまでです。みけCATさんありがとうございました。
ソートの方法を独学で学んでいるのですが、参考書をみて同じようにやってもエラーが出てしまいます。
ソートの方法だけでも教えていただきたいです。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
 
struct LeagueData {
    char team[20]; //チーム名
    int points;    //勝ち点
    int g_for;     //得点
    int g_against; //失点
    int g_diff;    //得失点差
}L_Data[];
int Compare(const void*s1, const void*s2) {
}
void DispTable(struct LeagueData *L_Data, int n)
{
 
}
int main() {
    int i;
    FILE*fp;
    fopen_s(&fp, "J_LEAGUE.txt", "r");
    if (fp == NULL) {
        printf_s("ファイルを開けませんでした.\n");
        return -1;
    }
    while (fscanf_s(fp, "%s %d %d %d ", L_Data[i].team, 25, &L_Data[i].points, &L_Data[i].g_for, &L_Data[i].g_against) != EOF){
        L_Data[i].g_diff = L_Data[i].g_for - L_Data[i].g_against;
        printf_s("%s %d %d %d %d \n", L_Data[i].team, L_Data[i].points, L_Data[i].g_for, L_Data[i].g_against, L_Data->g_diff);
    }
    fclose(fp);
    return 0;
}

Name: かずま
[URL]
Date: 2018年1月14日(日) 22:14
No: 4
(OFFLINE)

 Re: ファイルからデータを読み込んで並べ替えたいです

すきさほんきさ さんが書きました:いまできているのはファイルからデータを読み込むところまでです。

本当ですか?
  • そのコードをコンパイルすると、エラーメッセージが出ませんか?
  • L_Data[]; となっていますが、個数を指定しなくていいんですか?
  • char team[20]; なのに、fscanf_s で L_data[i].team, 25, なのは、なぜですか?
  • int i; はどこで初期化され、どこで更新されていますか?
  • L_Data[i].g_diff = L_Data[i].g_for - L_Data[i].g_against; なのに
    printf_s では、L_Data->g_diff でいいんですか?

以上の質問に返事がもらえれば、ソートの仕方をお教えしましょう。
サービスで、今は、Compare だけ書きますね。
コード[C]: 全て選択
1
2
3
4
5
6
7
int Compare(const void*s1, const void*s2)
{
    struct LeagueData *a = (struct LeagueData *)s1;
    struct LeagueData *b = (struct LeagueData *)s2;
    int diff = b->points - a->points;           // diff は勝ち点の差
    return diff ? diff : b->g_diff - a->g_diff; // 差がなければ、得失点差
}

Name: すきさほんきさ
[URL]
Date: 2018年1月15日(月) 15:50
No: 5
(OFFLINE)

 Re: ファイルからデータを読み込んで並べ替えたいです

かずま さんが書きました:
すきさほんきさ さんが書きました:いまできているのはファイルからデータを読み込むところまでです。

本当ですか?
  • そのコードをコンパイルすると、エラーメッセージが出ませんか?
  • L_Data[]; となっていますが、個数を指定しなくていいんですか?
  • char team[20]; なのに、fscanf_s で L_data[i].team, 25, なのは、なぜですか?
  • int i; はどこで初期化され、どこで更新されていますか?
  • L_Data[i].g_diff = L_Data[i].g_for - L_Data[i].g_against; なのに
    printf_s では、L_Data->g_diff でいいんですか?

以上の質問に返事がもらえれば、ソートの仕方をお教えしましょう


すみません。きちんとコンパイルせずにファイルからの読み込み、表示ができると言ってしまいました。
まずL_Dataの個数をチーム数の18にしました。
fscanf_sの引数の25はなんとなく多めにとっていただけです。20に訂正しました。
iは0で初期化しwhile文の最後で更新します。
printf_sのL_Data->g_diff も L_Data[i].g_diff に訂正しました。
コンパイルもきちんと通りました。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
 
struct LeagueData {
    char team[20]; //チーム名
    int points;    //勝ち点
    int g_for;     //得点
    int g_against; //失点
    int g_diff;    //得失点差
}L_Data[18];
int Compare(const void*s1, const void*s2)
{
    struct LeagueData *a = (struct LeagueData *)s1;
    struct LeagueData *b = (struct LeagueData *)s2;
    int diff = b->points - a->points;           // diff は勝ち点の差
    return diff ? diff : b->g_diff - a->g_diff; // 差がなければ、得失点差
}
 
//void DispTable(struct LeagueData *L_Data, int n)
//{
 
//}
int main() {
    FILE*fp;
    int i = 0;
    fopen_s(&fp, "J_LEAGUE.txt", "r");
    if (fp == NULL) {
        printf_s("ファイルを開けませんでした.\n");
        return -1;
    }
    while (fscanf_s(fp, "%s %d %d %d ", L_Data[i].team, 20, &L_Data[i].points, &L_Data[i].g_for, &L_Data[i].g_against) != EOF) {
        L_Data[i].g_diff = L_Data[i].g_for - L_Data[i].g_against;
        printf_s("%s %d %d %d %d \n", L_Data[i].team, L_Data[i].points, L_Data[i].g_for, L_Data[i].g_against, L_Data[i].g_diff);
        i++;
    }
    fclose(fp);
    return 0;
}

Name: かずま
[URL]
Date: 2018年1月15日(月) 16:36
No: 6
(OFFLINE)

 Re: ファイルからデータを読み込んで並べ替えたいです

コード[C]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
 
struct LeagueData {
    char team[20]; //チーム名
    int points;    //勝ち点
    int g_for;     //得点
    int g_against; //失点
    int g_diff;    //得失点差
} L_Data[18];
 
int Compare(const void*s1, const void*s2)
{
    struct LeagueData *a = (struct LeagueData *)s1;
    struct LeagueData *b = (struct LeagueData *)s2;
    int diff = b->points - a->points;           // diff は勝ち点の差
    return diff ? diff : b->g_diff - a->g_diff; // 差がなければ、得失点差
}
 
void DispTable(struct LeagueData *L_Data, int n)
{
    for (int i = 0; i < n; i++)
        printf_s("%-20s %d %d %d %d\n", L_Data[i].team, L_Data[i].points,
                L_Data[i].g_for, L_Data[i].g_against, L_Data[i].g_diff);
}
 
int main()
{
    FILE *fp;
    int i = 0;
    fopen_s(&fp, "J_LEAGUE.txt", "r");
    if (fp == NULL) {
        printf_s("ファイルを開けませんでした.\n");
        return -1;
    }
    while (fscanf_s(fp, "%s %d %d %d ", L_Data[i].team, 20, &L_Data[i].points,
                &L_Data[i].g_for, &L_Data[i].g_against) != EOF) {
        L_Data[i].g_diff = L_Data[i].g_for - L_Data[i].g_against;
        printf_s("%s %d %d %d %d \n", L_Data[i].team, L_Data[i].points,
                L_Data[i].g_for, L_Data[i].g_against, L_Data[i].g_diff);
        i++;
    }
    fclose(fp);
    puts("---");
    qsort(L_Data, i, sizeof(*L_Data), Compare);
    DispTable(L_Data, i);
    return 0;
}

qsort の第3引数は sizeof(struct LeagueData) でも構いません。

プログラムには、まだ改良すべき点がありますが、とりあえず、
これで初期の目標は達成できるでしょう。


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[12人]