6

I'd like to be able to add lines to the beginning of a file.

This program I am writing will take information from a user, and prep it to write to a file. That file, then, will be a diff that was already generated, and what is being added to the beginning is descriptors and tags that make it compatible with Debian's DEP3 Patch tagging system.

This needs to be cross-platform, so it needs to work in GNU C++ (Linux) and Microsoft C++ (and whatever Mac comes with)

(Related Threads elsewhere: http://ubuntuforums.org/showthread.php?t=2006605)

phuclv
  • 37,963
  • 15
  • 156
  • 475
Thomas Ward
  • 2,714
  • 7
  • 36
  • 51
  • possible duplicate of [In C++, what is the proper way to insert a line at the beginning of a text file?](http://stackoverflow.com/questions/4179349/in-c-what-is-the-proper-way-to-insert-a-line-at-the-beginning-of-a-text-file) – Bo Persson Jun 19 '12 at 20:09
  • Does look like a duplicate, but that other question doesn't have very good answers. – Jonathan Wakely Jun 19 '12 at 21:16
  • @JonathanWakely you know a better language that's cross platform? – Thomas Ward Jun 20 '12 at 02:49
  • For text processing? Sure, python. – Jonathan Wakely Jun 20 '12 at 10:52
  • @JonathanWakely I'll ask how to do this in Python too (in a different question), since I'd rather use python for linux platforms. I chose C++ because Linux, Mac, and Windows all can run C++ (no need to maintain two programs). Setting up python in Windows is... tricky might be the word... in order to get it correctly run – Thomas Ward Jun 20 '12 at 14:14

1 Answers1

12

See trent.josephsen's answer:

You can't insert data at the start of a file on disk. You need to read the entire file into memory, insert data at the beginning, and write the entire thing back to disk. (This isn't the only way, but given the file isn't too large, it's probably the best.)

You can achieve such by using std::ifstream for the input file and std::ofstream for the output file. Afterwards you can use std::remove and std::rename to replace your old file:

#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>

int main(){
    std::ofstream outputFile("outputFileName");
    std::ifstream inputFile("inputFileName");

    outputFile << "Write your lines...\n";
    outputFile << "just as you would do to std::cout ...\n";

    outputFile << inputFile.rdbuf();

    inputFile.close();
    outputFile.close();

    std::remove("inputFileName");
    std::rename("outputFileName","inputFileName");
    
    return 0;
}

Another approach which doesn't use remove or rename uses a std::stringstream:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

int main(){
    const std::string fileName = "outputFileName";
    std::fstream processedFile(fileName.c_str());
    std::stringstream fileData;

    fileData << "First line\n";
    fileData << "second line\n";

    fileData << processedFile.rdbuf();
    processedFile.close();

    processedFile.open(fileName.c_str(), std::fstream::out | std::fstream::trunc); 
    processedFile << fileData.rdbuf();

    return 0;
}
Gizmo
  • 871
  • 1
  • 15
  • 38
Zeta
  • 103,620
  • 13
  • 194
  • 236
  • 3
    The `while` loop can be replaced with `outputFile << inputFile.rdbuf();` – jxh Jun 19 '12 at 20:19
  • After writing to the other file, he can `remove` the original file, and `rename` the other file with the original name. May want to call `close` on the `fstream`s before doing that though. – jxh Jun 19 '12 at 20:37
  • Instead of using a `vector` why not just use a `stringstream`? – Jonathan Wakely Jun 19 '12 at 21:13
  • Thanks for the suggestions, I guess this wasn't one of at my best days :/… (`std::vector` instead of `std::stringstream`? Really? Damn, I believe I was asleep when I wrote that). – Zeta Jun 19 '12 at 22:22
  • Yes, that looks much better now :) – Jonathan Wakely Jun 20 '12 at 10:52