C++ 仅覆盖文件的特定部分

C++ 仅覆盖文件的特定部分,c++,io,fstream,C++,Io,Fstream,我知道这是真的,但我不明白答案 假设我有这样一个文件: Guest list: jon mary paul luke Table list: 然后,例如,我想更改客人的姓名。我知道我需要搜索字符串“Guest list”,然后覆盖“Guest list”和“Table list”之间的所有内容。但我不知道该怎么做 我使用C++,我更喜欢使用fSt:d 谢谢 编辑: 似乎用相对较小的文件编写一个全新的文件是最好的方法。我可能会使用这个方法来完成我现在想要做的事情。但我仍然对如何处理需要更新大型文

我知道这是真的,但我不明白答案

假设我有这样一个文件:

Guest list:
jon
mary
paul
luke
Table list:
然后,例如,我想更改客人的姓名。我知道我需要搜索字符串“Guest list”,然后覆盖“Guest list”和“Table list”之间的所有内容。但我不知道该怎么做

我使用C++,我更喜欢使用fSt:d

谢谢

编辑:


似乎用相对较小的文件编写一个全新的文件是最好的方法。我可能会使用这个方法来完成我现在想要做的事情。但我仍然对如何处理需要更新大型文件的情况非常感兴趣。

如果您可以将整个文件放入内存中(正如Space所指出的那样),请使用
ifstream
读入,并使用
ofstream
写出“来宾列表”行和所有新名称。这不是唯一的方法,但它是最方便的。

如果新的来宾姓名与旧的来宾姓名的长度不完全匹配,则无法就地执行替换,最好使用临时文件

  • 逐行读取原始文件,直到找到将每行复制到临时文件的“来宾列表:”分隔符
  • 将新来宾列表写入临时文件
  • 从原始文件中读取行,直到找到“表列表:”分隔符
  • 逐行读取原始文件,直到其结束,并将每一行复制到临时文件中
  • 删除原始文件。(或者在名称中添加备份扩展名,对其进行重命名。)
  • 将临时文件重命名为原始文件的名称
因此,这里有一些代码(这些问题并不像乍看起来那么简单):

#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
std::列表数据;
//逐行从文件加载数据
{//如果需要,可以将其设置为函数
std::ifstream文件(“test.txt”);
字符串缓冲区;
while(std::getline(文件、缓冲区))
数据。推回(缓冲区);
}//作用域结束-为我们关闭文件
//查找客人列表的末尾-这是添加新客人的地方
标准::列表::迭代器来宾列表结束=
std::find(data.begin()、data.end()、表列表:);
data.remove(“mary”);//从来宾列表中删除mary
data.insert(guest_list_end,“betty”);//将betty追加到guest list
data.insert(guest_list_end,“harry”);//将harry附加到guest list
//将整个文件写回
std::of流文件(“test.txt”);
std::copy(data.begin()、data.end(),
std::ostream_迭代器(文件“\n”);
}
由于您在本例中使用了
std::list
,因此迭代器
guest\u list\u end
仍然有效,即使在添加或删除guest时也是如此。请记住,列表中的
find
remove
具有线性复杂性,因此,如果文件很长,这可能会很昂贵


这段代码还假设guest后面是表列表。如果发生变化,您必须修改
find
-语句。

您可以链接到您不理解的答案吗?另外,你能把你的整个文件加载到内存中吗,或者它有那么大吗?我不会费心去更新文件的一部分——只要把全部内容读进去,然后再把全部内容写出来就行了。更新文本文件的某些部分太容易出错,也太乏味了。@Space这是一个问题:我知道一般要做的事情,但我不知道如何跳转到不同的行。是的,我可以把整个文件载入内存@特洛伊木马完全覆盖了文件,你是说?我会尝试这样做。不过,我想确保我做的很正确,因为我几乎没有在C++中处理文件的经验。如果您能编写一段代码来执行您提到的步骤,我将不胜感激。谢谢谢谢我只想问一件事:如果您不知道来宾列表和表列表之间的数据是什么,并且来宾列表不在文件的开头,该怎么办?
#include <iostream>
#include <fstream>
#include <list>
#include <string>
#include <iterator>
#include <algorithm>

int main()
{
    std::list<std::string> data;

    // load data from file line-by-line
    { // you can make this a function if you want
        std::ifstream file("test.txt");
        std::string buffer;
        while(std::getline(file, buffer))
            data.push_back(buffer);
    } // end of scope - file gets closed for us

    // find end of guest-list - this is where new guests are added
    std::list<std::string>::iterator guest_list_end = 
        std::find(data.begin(), data.end(), "Table list:");

    data.remove("mary"); // remove mary from guest-list
    data.insert(guest_list_end, "betty"); // append betty to guest-list
    data.insert(guest_list_end, "harry"); // append harry to guest-list

    // write entire file back
    std::ofstream file("test.txt");
    std::copy(data.begin(), data.end(), 
        std::ostream_iterator<std::string>(file, "\n"));
}