簡體   English   中英

如何更新預先存在的排行榜文本文件,確保已排序?

[英]How to I update a pre-existing leaderboard text file, making sure it's sorted?

首先,我要提前感謝大家花時間閱讀並幫助我解決我的問題。 我絕不是 c++ 的專家,我什至都不好。 我在 2 個月前開始在 c++ 中編程,我發現它比 python 更難,第二次體驗編程語言。 所以我正在為我的編程 class 制作這個游戲,我必須有一個包含某個級別的所有獲勝者的排行榜文本文件。 我對其進行了設置,因此文件始終具有相同的時間格式,名稱如下。

在此處輸入圖像描述

我一直在試圖弄清楚如何按時間和名稱對排行榜條目進行排序。 我想從第 3 行及以后讀取文件,但這似乎不起作用。 我轉向了一種似乎更好的方法,即讀取整個排行榜丟棄前兩行,將其逐行存儲在向量上,然后對向量進行排序並通過在 trunc 模式下打開文件來擦除文件,但對於文件沒有被擦除的某種原因,它只是不斷添加越來越多的條目。 我不希望將已排序的行(向量)一一添加到排行榜,直到命中 10 個條目。 有人能幫我嗎? 這是我用來更新排行榜的 function 的代碼

// Function to check if MAZE_XX_WINNERS.txt exists, if not creates it
void makeLeaderboard(string maze_name, string formated_time){
    
    string winner_name, filename = maze_name.substr(0,7) +"_WINNERS.txt";

    while(true){

        // If MAZE_XX_WINNERS.txt file exists
        if(ifstream(filename)){

            // Open MAZE_XX_WINNERS.txt file in append mode
            fstream leaderboard(filename, fstream::app);

            // Ask for player name
            cout << "Type your name (max 15 characters): ";
            getline(cin, winner_name);

            // If name is valid
            if(isValidName(winner_name) && winner_name.length() <= 15){
                
                string line;
                vector<string> lb_entries;
                int n_line = 0;

                // Append to the end of the file
                leaderboard << formated_time << " - " << winner_name << endl;

                // Store all leaderboard entries in a vector
                while(!leaderboard.eof()){

                    if(n_line >= 2){
                        getline(leaderboard, line);
                        lb_entries.push_back(line);
                    }
                    n_line++;
                }
                leaderboard.close();

//Everything works up until here, past here it doesn't do anything I want it to do

                // Sort the leaderboard entries first by time, then by name
                sort(lb_entries.begin(), lb_entries.end());

                // Check if leaderboard has more than 10 entries to delete those past the limit
                if(lb_entries.size() > 10){
                    
                    // Truncates the vector from the 10th position forward
                    lb_entries.erase(lb_entries.begin()+9, lb_entries.end());
                }

                // Reopens the file in truncation mode to delete pre-existing leaderboard
                leaderboard.open(filename, fstream::trunc);

                // Format the file to have a table like shape
                leaderboard << "|    TIME    -      NAME     |" << endl;
                leaderboard << "------------------------------" << endl;

                // Updates leaderboard
                for(string entry : lb_entries){
                    leaderboard << entry << endl;
                }
                
                leaderboard.close();
                break;
            }
            // If name not valid
            else if(isValidName(winner_name) && winner_name.length() > 15){
                cerr << endl << "Name has more than 15 characters! Please retry." << endl << endl;
            }
            else{
                cerr << endl << "Not a valid name input!" << endl << endl;
            }
        }
        // If file doesn't exist
        else{

            // Attempt to create the file
            cout << "Creating leaderboard..." << endl;
            ofstream leaderboard(filename);

            // Check if file was created
            if(!leaderboard){
                cerr << "File could not be created" << endl;
            }
            else{

                // Format the file to have a table like shape
                leaderboard << "|    TIME    -      NAME     |" << endl;
                leaderboard << "------------------------------" << endl;

                leaderboard.close();
            }
        }
    }
}

你需要分解你的問題。 我要做的是創建一個代表排行榜的 class。 它實際上由兩個類組成。 您可以將其中一個作為其他內部 class 進行,但讓我們將它們分開:

class Leader {
public:
     std::string time;
     std::string name;
};

class LeaderBoard {
public:
     std::vector<Leader> leaders;
     void readFromFile(std::string fName);
     void sort();
     void writeToFile(std::string fName);
};

此時,您需要實現三個功能。 它們都不是很長。

void LeaderBoard::readFromFile(std::string fName) {
    std::ifstream file(fName);
    std::string line;

    // skip the header
    file.getline(line);
    file.getline(line);

    // Read the rest of the file.
    while (file.getline(line)) {
         // You'll need to parse the line into its parts
         Leader leader(from the parts);
         leaders.push_back(leader);
    }
}

是的,我給你留下了一些魔法。

write 方法將非常簡單,只需使用 ofstream 而不是 ifstream。

排序方法——你可以在谷歌上搜索“c++ sort vector of objects”並獲得大量示例。


一般來說,所有的編程都可以分解成更小的步驟。 如果你感到不知所措,那就打破它。 這是您使用面向對象語言的原因之一。 如果您不知道如何做某事,請為其創建一個 class,然后將方法放入其中以進行較小的步驟。

然后只需弄清楚如何一次做小部分。 第一:獲取數據。 然后打印出來,這樣你就確定你已經得到了你需要的東西。

如果您的代碼不僅僅是一個屏幕左右,那么您在一種方法中做的太多了。 這不是絕對的,但在你的編碼水平上,這絕對是真的。

小而緊的方法。 小而緊的方法更容易編寫。 然后將它們串在一起。

在這種情況下:

  1. 讀取數據
  2. 對數據進行排序
  3. 寫入數據。

每一個都很容易單獨測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM