0

I'm trying to write a program that can open a text file, find a certain string and substitute it with another string and then write the altered text to an output file.

This is what I've coded so far. It works fine, except for that the output file is missing spaces and new line characters.

I need to preserve all spaces and new line characters. How do I do it?

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



using namespace std;



int main()
{
    string search = "HELLO";        //String to find
    string replace = "GOODBYE"; //String that will replace the string we find
    string filename = "";   //User-provided filename of the input file
    string temp;            //temp variable for our loop to hold the characters from the file stream
    char c;


    cout << "Input filename? ";
    cin >> filename;


    ifstream filein(filename);      //File to read from
    ofstream fileout("temp.txt");   //Temporary file


    if (!fileout || !filein)        //if either file is not available
    {
        cout << "Error opening " << filename << endl;
        return 1;
    }


    while (filein >> temp)  //While the stream continues
    {

        if (temp == search) //Check if the temp variable has captured the string we are looking for
        {

            temp = replace; //When we found the string, we substitute it with the replacement string

        }

        fileout << temp;    //Dump everything to fileout (our temp.txt file)

    }

    //Close our file streams

    filein.close();
    fileout.close();

    return 0;
}

UPDATE:

I followed your advice and did the following, but now it doesn't work at all (the previous code worked fine, except for white spaces). Could you kindly tell me what I'm doing wrong here? Thank you.

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



using namespace std;



int main()
{
    string search = "or";       //String to find
    string replace = "OROROR";  //String that will replace the string we find
    string filename = "";   //User-provided filename of the input file
    string temp = "";           //temp variable for our loop to hold the characters from the file stream
    char buffer;


    cout << "Input filename? ";
    cin >> filename;


    ifstream filein(filename);      //File to read from
    ofstream fileout("temp.txt");   //Temporary file


    if (!fileout || !filein)        //if either file is not available
    {
        cout << "Error opening " << filename << endl;
        return 1;
    }



    while (filein.get(buffer))  //While the stream continues
    {

        if (buffer == ' ') //check if space
        {

            if (temp == search) //if matches pattern, 
            {

                temp = replace; //replace with replace string

            }

        }

        temp = string() + buffer;

        for (int i = 0; temp.c_str()[i] != '\0'; i++)
        {
            fileout.put(temp.c_str()[i]);
        }






        return 0;
    }

}
6
  • Extracting tokens from a stream skips whitespaces by default. You need to add them manually. In addition, if you are not reopening the streams, calling close() is redundant. std::fstream's destructor does that for you Commented Oct 14, 2018 at 22:21
  • As far as close() goes, we've been to do it by our professor. As far as adding white spaces, how can I add them manually if it's not just white spaces it skips, but also new lines. How would I know whether to add a newline of a white space? Commented Oct 14, 2018 at 22:32
  • Newlines are also whitespaces. I am working on an answer below. Should be ready in 5 minutes Commented Oct 14, 2018 at 22:33
  • She will literally deduct points if we don't use close(). Commented Oct 14, 2018 at 22:34
  • Seems like Sam posted his answer first. It's a good one. As for your teacher - you might want to calmly inform her that RAII has been a part of C++ for over 20 years and maybe she would like to upgrade her knowledge to match the one from the end of the previous millennium. Just saying Commented Oct 14, 2018 at 22:40

1 Answer 1

1
while (filein >> temp)

This temp variable is a std::string. The formatted extraction operator, >>, overload for a std::string skips all whitespace characters (spaces, tabs, newlines) in the input and completely discards them. This formatted extraction operator discards all whitespace until the first non-whitespace character, then extracts it and all following non-whitespace characters and places them into your std::string, which is this temp variable. This is how it works.

Subsequently:

fileout << temp;

This then writes out this string to the output. There's nothing in the shown code that tells your computer to copy all whitespace from the input to the output, as is. The only thing that the shown code does is extract every sequence of non-space characters from the input file, immediately throwing on the floor all spaces and newlines, never to be seen again; and then write what's left (with the appropriate changes) to the output file. And a computer will always do exactly what you tell it to do, and not what you want it to do.

while (filein >> temp)

This is where all spaces in the input file gets thrown in the trash, and discarded. Therefore you wish to preserve them and copy them to the output file, as is, you will have to replace this.

There are several approaches that can be used here. The simplest solution is to simply read the input file one character at a time. If it's not a whitespace character, add it to the temp buffer. If it's a whitespace character, and temp is not empty, then you've just read a complete word; check if it needs replacing; write it out to the output file; clear the temp buffer (in preparation for reading the next word); and then manually write the just-read whitespace character to the output file. In this manner you will copy the input to the output, one character at a time, including spaces, but buffering non-space character into the temp buffer, until each complete word gets read, before copying it to the output file. And you will also need to handle the edge case of handling the very last word in the file, without any trailing whitespace.

Sign up to request clarification or add additional context in comments.

1 Comment

You did not implement what I wrote down, exactly. Reread my answer, carefully, and compare it with your own code. Try to find which part of your new code correctly implements everything I wrote down in the 4th sentence of the 2nd paragraph. You will not find it because you did not implement it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.