Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何更新预先存在的排行榜文本文件,确保它';分类了吗?_C++_File - Fatal编程技术网

C++ 如何更新预先存在的排行榜文本文件,确保它';分类了吗?

C++ 如何更新预先存在的排行榜文本文件,确保它';分类了吗?,c++,file,C++,File,首先,我想提前感谢大家花时间阅读并帮助我解决问题。我根本不可能形成或形成C++专家,我甚至不好。我开始在C++编程2个月前,我发现它比Python更难,第二次编程语言的经验。 所以我为我的编程课制作了这个游戏,我必须有一个排行榜文本文件,上面有某个级别的所有获奖者。我将其设置为使文件始终具有相同的时间格式,名称如下 我一直在想如何按时间和名字对排行榜条目进行排序。我想从第3行或更高的位置读取文件,但这似乎不起作用。我接着看了一个似乎更好的方法,那就是阅读整个排行榜,丢弃前2行,将其逐行存储在向

首先,我想提前感谢大家花时间阅读并帮助我解决问题。我根本不可能形成或形成C++专家,我甚至不好。我开始在C++编程2个月前,我发现它比Python更难,第二次编程语言的经验。 所以我为我的编程课制作了这个游戏,我必须有一个排行榜文本文件,上面有某个级别的所有获奖者。我将其设置为使文件始终具有相同的时间格式,名称如下

我一直在想如何按时间和名字对排行榜条目进行排序。我想从第3行或更高的位置读取文件,但这似乎不起作用。我接着看了一个似乎更好的方法,那就是阅读整个排行榜,丢弃前2行,将其逐行存储在向量上,然后对向量进行排序,并通过在trunc模式下打开文件来擦除文件,但由于某种原因,文件没有被擦除,只是不断添加越来越多的条目。我不想一个接一个地将排序的行(向量)添加到排行榜,直到命中10个条目。有人能帮我吗?下面是我用来更新排行榜的函数的代码

// 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();
            }
        }
    }
}
//用于检查MAZE_XX_WINNERS.txt是否存在的函数,如果不存在,则创建它
void makeLeaderboard(字符串名称、字符串格式化时间){
字符串winner\u name,filename=maze\u name.substr(0,7)+“\u WINNERS.txt”;
while(true){
//如果MAZE_XX_WINNERS.txt文件存在
if(ifstream(文件名)){
//以附加模式打开MAZE_XX_WINNERS.txt文件
fstream排行榜(文件名,fstream::app);
//询问玩家姓名

cout您需要将问题分解。我要做的是创建一个代表排行榜的类。它实际上由两个类组成。您可以将其中一个类作为其他类的内部类,但让我们将它们分开:

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);
};
是的,我给你留了一些魔法

write方法非常简单,只需使用ofstream而不是ifstream

排序方法——您可以在google上搜索“c++对象排序向量”,并获得大量示例


一般来说,所有的编程都可以分解为更小的步骤。如果您感到不知所措,请将其分解。这是您使用面向对象语言的原因之一。如果您不知道如何做某件事,请为其创建一个类,然后为更小的步骤在其中放入方法。 然后,只需找出如何一次完成一小部分。首先:获取数据,然后打印出来,这样你就可以确定你已经得到了你所需要的

如果你的代码不仅仅是一个屏幕,那么你在一种方法中做的太多了。这不是绝对的,但在你的编码水平上,这是绝对正确的

小而紧凑的方法。小而紧凑的方法更容易编写。然后将它们串在一起

在这种情况下:

  • 读取数据
  • 对数据进行排序
  • 写下数据

  • 每一个都很容易单独测试。

    尝试使用
    trunc
    作为openmode来读取文件将失败。它需要与
    out
    配对。您也没有读入文件,因为您打开它,附加新记录,然后尝试读取现有记录。这不会读取任何内容,因为您将从文件结尾,刚刚在那里写了。很抱歉,我没有完全理解你要我做的事情,你能给我一些代码示例,让我可以比较并从错误中学习吗?好的,经过一些尝试和错误,我终于明白了你的意思。我交换了这行代码
    leadboard.open(filename,fstream::trunc)
    与此一起
    排行榜。打开(文件名,fstream::trunc | fstream::out | fstream::app)
    但现在我有另一个问题。该程序正在通过排序排行榜或阻止超过10条条目来更新其内容。它只是在底部添加内容。我感觉我要后退了。非常感谢您的建议。我非常感谢,并将尽可能地使用它来改进。关于你对我的问题的解决方案:我们选择离开类和结构,因为我们刚刚开始学习语言。我们将在项目完成后转移到更难的概念。不过,我想我将能够接受你认为我的东西,并调整它以适应函数而不是类。
    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);
        }
    }