C++ Inserting a line at specific point in file
我有一个包含游戏高分的文本文件,格式如下:
1
2 3 |
Name Score
Name Score Name Score |
文件按分数降序排列。
我想在文件的正确位置插入一个新名称及其对应的分数,以便它保持正确排序。任何建议如何做到这一点将不胜感激!
例如,给定以下文件:
1
2 3 4 |
Edward 100
David 90 Sarah 80 Alice 60 |
我想补充一下。
1
2 |
Name = Jodi
Score = 70 |
到文件,所以新文件的内容是:
1
2 3 4 5 |
Edward 100
David 90 Sarah 80 Jodi 70 Alice 60 |
谢谢
目前我有以下代码:
1
2 3 4 5 6 7 |
string playerName = pPlayer–>GetName(); int playerScore = pPlayer–>GetScore(); std::ofstream score("scores.txt", std::ios_base::app | std::ios_base::out); score <<"/ |
这只是将名称添加到文件的末尾。我考虑阅读整个文件,然后对旧文件进行排序。但我不想这样做,因为如果文件变大可能需要很长时间。
有几种不同的方法可以做到这一点。最简单的实现是将整个文件读入向量,插入新值并写出新文件。
第二个选项是读取文件,直到找到正确的位置,”标记”在文件中的位置(例如使用
第三种选择是在文件中保持列表无序,并在阅读时对信息进行排序。这样,您可以只追加到末尾,从而节省了一遍又一遍地写入文件。
实际上,我怀疑编写一个非常大的文件仍然足够快,几乎不会产生任何影响。现代硬盘驱动器每秒将写入数兆字节,而每行只有几十个字节,因此文件中需要有数百万行才能产生任何影响。比如我刚刚在我的机器上复制了一些132MB的大文件,读取和写入132MB的时间为1.2s。如果你的每条记录都是 26 字节,那就是 5000 万个”分数”。
如果你仔细定义一个类型来表示你的数据记录:
1
2 3 4 5 6 7 8 9 |
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 { |
注意它知道如何
- 从流中读取记录
- 将其写回流
- 按分数比较记录
那么,C 算法又是你的朋友了:
1
2 3 4 5 6 7 8 9 10 11 |
int main() { std::ifstream ifs("input.txt"); std::vector<Record> const insert { Record {"Jodi", 70 } }; std::merge( |
在 Coliru 现场观看
一种方法是加载文件,然后在包含新数据的情况下重写它:
1) 您必须使用 C 文件处理 API(或任何您认为更好的 API)将文件加载到结构中。
2) 由于按顺序加载,数据将在结构中排序。然后,您必须在结构中添加所需的节点(新数据),使其保持排序状态。
3) 最后,从结构中重写你的文件。
对于您的情况,您可以使用
然后,将您的数据放入结构中,以使其保持排序状态。例如,您可以分割一条线,然后获取分数部分,将其解析为
打开文件并逐行重写。
它的行为方式取决于文件系统。一般没有解决办法。但我不认为有一个真实的文件系统可以让你做这些事情。
关于这样的操作前后文件在磁盘上的样子。文件是磁盘上的一大块。所以重写是需要完成的动作。
如果您对一些不同的方法持开放态度,可能会有解决方案。把这个文件想象成内存。如果它不在磁盘上,你会怎么做?您可以在数组中使用哪种数据结构(我们可以将文件定义为数组)?
如果您不想创建自己的,使用 sth,就完成了。我个人会使用数据库来完成这样的任务。这正是你想要的。您可以插入数据,然后对其进行排序,并且运行速度很快。它经过优化,可以在硬盘驱动器等环境中工作。如果你想把它存档,你可以使用
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/268929.html