2

I know this was asked once, but I didn't understand the answer.

Let's say I have a file like this:

Guest list:
jon
mary
paul
luke
Table list:

And then, for example, I want to change the names of the guests. I understood that I need to search for the string "Guest list" and then overwrite everything between "Guest list" and "Table list". But I have no idea how to do that.

I'm using C++, and I prefer using fstream :D

Thanks !

edit:

It seems that writing a completely new file is the best method with relatively small files. I'll probably use this method for what I want to do now. But I'm still really interested in how to handle situations where you need to update a huge file.

Community
  • 1
  • 1
Lockhead
  • 2,423
  • 7
  • 35
  • 48
  • 4
    Can you link to the answer you did not understand? Also, can you load your entire file into memory, or is it that big? – Björn Pollex Mar 30 '11 at 13:42
  • 1
    I wouldn't bother trying to update parts of the file - just read the whole lot in and write the whole lot out again. Updating parts of a text file is too error-prone and tedious. – trojanfoe Mar 30 '11 at 13:47
  • @Space It's this question: http://stackoverflow.com/questions/2530274/how-to-overwrite-only-part-of-a-file-in-c I understood the general thing to do but I have no idea how to jump to different lines. And yeah, I can load the entire file into memory. @trojanfoe Completely overwriting the file, you mean? – Lockhead Mar 30 '11 at 13:58

3 Answers3

3

If the new guest names do not match exactly the length of the old guest names, you can't perform the replacement in-place, it's best to use a temporary file.

  • Read the original file line-by-line until you locate the "Guest list:" delimiter copying each line to the temporary file.
  • Write the new guest list to the temporary file.
  • Read lines from the original file until you locate the "Table list:" delimiter.
  • Read the original file line-by-line until its end, copying each line to the temporary file.
  • Delete the original file. (Or rename it adding a backup extension to its name.)
  • Rename the temporary file to the name of the original file.
Diomidis Spinellis
  • 18,734
  • 5
  • 61
  • 83
  • I'll try doing something like that. Still, I want to be sure that I do it correctly because I have almost no experience with file handling in C++. If you could write a snippet of code performing the steps that you mentioned I will greatly appreciate it. Thanks! – Lockhead Mar 30 '11 at 14:32
0

If you can fit the entire file in memory (as Space had pointed out), read it in using an ifstream, and, using an ofstream write out the "Guest List" line, and all of the new names. It's not the only way, but it's the most convenient.

jonsca
  • 10,218
  • 26
  • 54
  • 62
0

So, here is some code (these kinds of problems are not as simple as they seem at first glance):

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

Since you this example uses an std::list, the the iterator guest_list_end remains valid, even when we add or remove guests. Keep in mind that find and remove on lists have linear complexity, so if the file is long, this might be costly.

This code also assumes that the guest is followed by the table list. If that changes, you have to modify the find-statement.

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • Thanks! There's just one thing I want to ask: What if you have no idea what data is between Guest list and Table list and Guest list is not at the beginning of the file? – Lockhead Mar 30 '11 at 14:52