C++ 在文件中的特定点插入一行

C++ Inserting a line at specific point in file

本文关键字:插入 一行 文件 C++      更新时间:2023-10-16

我有一个文本文件,其中包含以下格式的游戏高分:

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并与新数据分数进行比较。之后,结构包含您的数据状态。打开文件并逐行重写。