[C++] 255 SDL : テトリス画面にベストスコア5つを表示 その3 CSVファイル読み込み ChatGPT

[M1 Mac, Monterey 12.6.3, clang 13.0.0, SDL 2.26.2, ChatGPT Plus, NO IDE]

テトリスのプレイ記録をCSVファイルにまとめ、起動時にこれを読み込んでスコアのベスト5を表示させるようにします。

まずテスト用のCSVファイルについて、これを読み込んで必要なデータをvectorにまとめるコードをChatGPTに書いてもらいました。

内容を検証したところ正常に動作して、最後にvectorの内容を出力してくれるという120点の出来でした。ハマると素晴らしいコードを書いてくれます。

Q:
score,date,playtime
0,2020-03-01 14:20:30,25:00
800,2020-03-03 19:10:45,20:30
500,2020-03-07 08:15:20,15:00
300,2020-03-01 15:22:00,12:30
20,2020-02-20 23:55:09,10:00
1000,2020-02-07 23:55:09,10:00 
C++でこのcsvファイルを読み込み、scoreで降順ソートして上位5件のscoreと月/日をそれぞれvector<int>,vector<string>にして下さい。

以下は、与えられたCSVファイルを読み込み、スコアで降順ソートして上位5件のスコアと日付(月/日)をそれぞれvector<int>とvector<string>に格納するサンプルコードです。

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>

struct Entry {
    int score;
    std::string date;
    std::string playtime;
};

// CSVファイルを読み込み、各行をEntry構造体に変換してvectorに格納する
std::vector<Entry> ReadCSV(const std::string& filename) {
    std::vector<Entry> entries;

    std::ifstream infile(filename);
    if (!infile) {
        std::cerr << "Failed to open file: " << filename << std::endl;
        return entries;
    }

    std::string line;
    std::getline(infile, line); // ヘッダ行を読み飛ばす
    while (std::getline(infile, line)) {
        std::istringstream iss(line);
        std::string score_str, date, playtime;
        std::getline(std::getline(iss, score_str, ','), date, ',');
        std::getline(iss, playtime, ',');
        int score = std::stoi(score_str);
        entries.push_back({score, date, playtime});
    }

    return entries;
}

int main() {
    std::vector<Entry> entries = ReadCSV("scores.csv");

    // スコアで降順ソート
    std::sort(entries.begin(), entries.end(),
              [](const Entry& a, const Entry& b) { return a.score > b.score; });

    // 上位5件を取得して、スコアと日付をvectorに格納
    std::vector<int> top_scores;
    std::vector<std::string> dates;
    for (int i = 0; i < std::min(5, static_cast<int>(entries.size())); ++i) {
        top_scores.push_back(entries[i].score);
        std::string month_day = entries[i].date.substr(5, 5);
        dates.push_back(month_day);
    }

    // 結果を出力
    std::cout << "Top 5 scores:" << std::endl;
    for (int i = 0; i < static_cast<int>(top_scores.size()); ++i) {
        std::cout << top_scores[i] << ", " << dates[i] << std::endl;
    }

    return 0;
}

上記のコードを実行すると、出力結果が表示されます。

Top 5 scores:
1000, 02-07
800, 03-03
500, 03-07
300, 03-01
20, 02-20