Babbu Maan
Babbu Maan

Reputation: 149

Using fstream write

I am trying to look for a line in a specified file and replace it with my line. I don’t have access to the library on the machines I’ll be running this on, so I created a custom file. The trouble seems to be the write call to the fstream object. I was wondering if any of you can help. Also, my getline loop stops before reaching the end of the file, and I am not sure why.

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

#define TARGET2 "Hi"

using namespace std;

void changeFile(string fileName){
    fstream myStream;
    myStream.open(fileName.c_str(),fstream::in | fstream::out);     

    string temp;
    string temp2 = "I like deep dish pizza";    

    while(getline(myStream, temp)){
        if(temp == TARGET2){
            cout << "Match" << endl;
            myStream.write(temp2.c_str(), 100);
            myStream << temp2 << endl;
            cout << "No runtime error: " << temp2 << endl;                  
        }
        cout << temp << endl;
    }
    myStream.close();
}

int main (void){        
    changeFile("Hi.txt");
    return 0;
}

Hi.txt

Hi
Today is June 18
I like pizza
I like pepperoni

The output is:

Match
No runtime error: I like deep dish pizza
Hi

Upvotes: 4

Views: 34804

Answers (1)

Brendan Long
Brendan Long

Reputation: 54242

myStream.write(temp2.c_str(), 100);
myStream << temp2 << endl;

Why are you writing this to the file twice, and why are you telling it that "I like deep dish pizza" is 100 characters long? Just using the second line alone should do what you want.

I think the reason the loop is ending is that you're writing the file as you read it, which causes getline to be confused. If the file is small, I would just read the whole thing into a stringstream, replacing the line you want to replace, then write the whole stringstream out to a file. Changing the file in-place is much harder.

Example:

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

int main(int argc, char** argv) {

    /* Accept filename, target and replacement string from arguments for a more
       useful example. */
    if (argc != 4) {
        std::cout << argv[0] << " [file] [target string] [replacement string]\n"
            << "    Replaces [target string] with [replacement string] in [file]" << std::endl;
        return 1;
    }

    /* Give these arguments more meaningful names. */
    const char* filename = argv[1];
    std::string target(argv[2]);
    std::string replacement(argv[3]);

    /* Read the whole file into a stringstream. */
    std::stringstream buffer;
    std::fstream file(filename, std::fstream::in);
    for (std::string line; getline(file, line); ) {
        /* Do the replacement while we read the file. */
        if (line == target) {
            buffer << replacement;
        } else {
            buffer << line;
        }
        buffer << std::endl;
    }
    file.close();

    /* Write the whole stringstream back to the file */
    file.open(filename, std::fstream::out);
    file << buffer.str();
    file.close();
}

Run like:

g++ example.cpp -o example
./example Hi.txt Hi 'I like deep dish pizza'

Upvotes: 8

Related Questions