我有一个文本文件,其中包含此格式的游戏高分:
Name Score
Name Score
Name Score
文件按得分降序排列。
我想在文件的正确位置插入一个新名称及其对应的分数,以便它保持正确排序。任何建议如何做到这一点将不胜感激!
例如,给出以下文件:
Edward 100
David 90
Sarah 80
Alice 60
我想补充一下。
Name = Jodi
Score = 70
到文件中,新文件显示为:
Edward 100
David 90
Sarah 80
Jodi 70
Alice 60
由于
目前我有以下代码:
string playerName = pPlayer->GetName();
int playerScore = pPlayer->GetScore();
std::ofstream score("scores.txt", std::ios_base::app | std::ios_base::out);
score << "\n" << playerName << " " << playerScore;
只是将名称添加到文件末尾。我考虑在整个文件中进行读取,然后对旧文件进行修改。但我不想这样做,因为如果文件变大,可能需要很长时间。
答案 0 :(得分:4)
有几种不同的方法可以做到这一点。最简单的实现是将整个文件读入向量,插入新值并写出新文件。
第二个选项是读取文件,直到找到正确的位置,&#34;标记&#34;在文件中的位置(例如使用istream::tellg()
),然后将所有以下元素读入向量,更新新记录,并在此之外写回一次。
第三种选择是将列表无序保存在文件中,并在读取时对信息进行排序。这样,你可以追加到最后,节省了一遍又一遍地写文件。
实际上,我怀疑写一个非常大的文件仍然足够快,几乎没有差别。现代硬盘每秒会写出几兆字节,而每行只有几十个字节,所以你需要在你的文件中有数百万行才能产生任何差别。例如,我只是在我的机器上复制了一些大小为132MB的大文件,读取和写入132mb的合理时间达到了1.2s。如果你的每个记录都是26个字节,那就是5000万&#34;得分&#34;。
答案 1 :(得分:2)
如果您仔细定义了表示数据记录的类型:
struct Record {
std::string name; int score;
friend std::istream& operator>>(std::istream& is, Record& r) { return is >> r.name >> r.score; }
friend std::ostream& operator<<(std::ostream& os, Record const& r) { return os << r.name << "\t" << r.score; }
bool operator<(Record const& other) const {
return other.score < score;
}
};
请注意,它知道如何
然后,C ++算法再次成为你的朋友:
int main()
{
std::ifstream ifs("input.txt");
std::vector<Record> const insert { Record { "Jodi", 70 } };
std::merge(
std::istream_iterator<Record>(ifs), {},
insert.begin(), insert.end(),
std::ostream_iterator<Record>(std::cout, "\n"));
}
答案 2 :(得分:0)
它的行为取决于文件系统。一般没有解决方案。但我不认为有一个真实的文件系统,你可以做这些事情。
关于文件在这样的操作之前和之后如何在磁盘上查看。文件是磁盘上的一大块。因此,重写是需要完成的行动。
如果您对某些不同的方法持开放态度,可能会有解决方案。想想这个文件就像记忆一样。如果它不在磁盘上,你会怎么做?您可以在数组中使用哪种数据结构(我们可以将文件视为数组)?
如果你不想创建自己的,请使用sth,这已完成。我个人会用数据库来完成这样的任务。这正是你想要的。您可以插入数据然后对其进行排序,并且它可以快速运行。它经过优化,适用于硬盘等环境。如果您想将其存档,可以使用SQLite
。
答案 3 :(得分:0)
一种方法是加载文件,然后重写它并包含新数据:
1)您必须使用C ++文件处理API(或任何您认为更好的API)在结构中加载文件。
2)由于按顺序加载,数据将在结构中排序。然后,您必须按照保持排序的顺序在结构中添加所需的节点(新数据)。
3)最后,从结构中重写文件。
对于您的情况,您可以使用std::vector
。您可以打开该文件并将其所有行加载到该向量中。您可以通过执行字符串操作来隔离数据。
然后,将您的数据放入结构中,以便保持排序。例如,您可以拆分一条线然后取得分数部分,将其解析为int
并与新的数据分数进行比较。之后,结构包含您的数据状态。
打开文件并逐行重写。