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

时间:2014-04-04 22:11:43

标签: c++ string file-io

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

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;

只是将名称添加到文件末尾。我考虑在整个文件中进行读取,然后对旧文件进行修改。但我不想这样做,因为如果文件变大,可能需要很长时间。

4 个答案:

答案 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"));
}

查看 Live On Coliru

答案 2 :(得分:0)

它的行为取决于文件系统。一般没有解决方案。但我不认为有一个真实的文件系统,你可以做这些事情。

关于文件在这样的操作之前和之后如何在磁盘上查看。文件是磁盘上的一大块。因此,重写是需要完成的行动。

如果您对某些不同的方法持开放态度,可能会有解决方案。想想这个文件就像记忆一样。如果它不在磁盘上,你会怎么做?您可以在数组中使用哪种数据结构(我们可以将文件视为数组)?

如果你不想创建自己的,请使用sth,这已完成。我个人会用数据库来完成这样的任务。这正是你想要的。您可以插入数据然后对其进行排序,并且它可以快速运行。它经过优化,适用于硬盘等环境。如果您想将其存档,可以使用SQLite

答案 3 :(得分:0)

一种方法是加载文件,然后重写它并包含新数据:

1)您必须使用C ++文件处理API(或任何您认为更好的API)在结构中加载文件。

2)由于按顺序加载,数据将在结构中排序。然后,您必须按照保持排序的顺序在结构中添加所需的节点(新数据)。

3)最后,从结构中重写文件。

对于您的情况,您可以使用std::vector。您可以打开该文件并将其所有行加载到该向量中。您可以通过执行字符串操作来隔离数据。 然后,将您的数据放入结构中,以便保持排序。例如,您可以拆分一条线然后取得分数部分,将其解析为int并与新的数据分数进行比较。之后,结构包含您的数据状态。 打开文件并逐行重写。