C++ 在文件中的特定点插入一行
C++ Inserting a line at specific point in file
我有一个文本文件,其中包含以下格式的游戏高分:
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;
它只是将名称添加到文件的末尾。我考虑阅读整个文件排序,然后纠正旧文件。但我不想这样做,因为如果文件变大,可能需要很长时间。
有几种不同的方法可以做到这一点。最容易实现的一种是将整个文件读入向量,插入新值并写出新文件。
第二种选择是读取文件,直到找到正确的位置,"标记"文件中的位置(例如使用 istream::tellg()
),然后将以下所有元素读取到向量中,更新新记录,然后写回一次超出该位置。
第三种选择是仅将列表中的列表保持在文件中的无序状态,并在阅读信息时对信息进行排序。这样,您可以直接附加到末尾,从而节省一遍又一遍地写入文件的时间。
实际上,我怀疑编写一个非常大的文件仍然足够快,几乎没有或根本没有区别。现代硬盘驱动器每秒将写入数兆字节,而每行只有几十个字节,因此您需要在文件中包含数万行才能产生任何差异。例如,我刚刚在我的机器上复制了一些总计 132MB 的大文件,读写 132MB 的压缩时间达到了 1.2 秒。如果你的每条记录都是 26 个字节,那就是 5000 万个"分数"。
如果仔细定义一个类型来表示数据记录:
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"));
}
在科里鲁现场观看
它的行为方式取决于文件系统。一般没有解决方案。但我不认为有一个现实生活中的文件系统可以做这样的事情。
关于在此类操作之前和之后文件在磁盘上的外观。文件是磁盘上的一个大块。所以重写是需要采取的行动。
如果您对一些不同的方法持开放态度,可能会有一个解决方案。把这个文件想象成关于内存。如果它不在磁盘上,您将如何执行此操作?你可以在数组中使用哪种数据结构(我们可以像对待数组一样对待文件)?
如果您不想创建自己的,请使用 sth,这已经完成了。就个人而言,我会使用数据库来完成此类任务。这正是你想要的。您可以插入数据,然后对其进行排序,并且效果很快。它经过优化,可在硬盘驱动器等环境中工作。如果您想将其存档,可以使用 SQLite
.
一种方法是加载文件,然后在包含新数据的情况下重写它:
1)您必须使用文件处理API(或任何您可能认为更好的API)将文件加载到结构中C++。
2)由于是按顺序加载的,数据将在结构中排序。然后,您必须按照保持排序的顺序在结构中添加所需的节点(新数据)。
3)最后,从结构重写文件。
对于您的情况,您可以使用std::vector
。您可以打开文件并将其所有行加载到该向量中。可以通过执行字符串操作来隔离数据。然后,将数据放入结构中,使其保持排序状态。例如,您可以拆分一条线,然后获取分数部分,将其解析为int
并与新数据分数进行比较。之后,结构包含您的数据状态。打开文件并逐行重写。
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 预处理器:插入结构名称中的前一个行号
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 在未初始化映射的情况下,将值插入到映射的映射中
- 从C++dll访问C#中的一行主要参数
- 如何在c++中只将键插入到bimap的一侧
- 如何将结构插入到集合中并打印集合的成员
- C++json插入数组
- 我可以在一行代码中将向量中与条件匹配的所有元素插入到集合中吗?
- 在每个特定字符串之后插入下一行
- 如何在Visual Studio 2013 Ultimate Edition中包含某个单词的每一行中插入断点
- 从.txt文件中读取一行,然后插入变量
- 在 MySQL 中使用 MFC 对话框基础应用的C++插入一行
- C++在文件中的一行中搜索某些单词,然后在这些单词后面插入一个单词
- 最有效的方式插入一行bool值到原始数组
- 在一行中插入多个无空格的整数
- C++ 在文件中的特定点插入一行