Reputation: 431
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;
}
}
Upvotes: 0
Views: 947
Reputation: 118350
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.
Upvotes: 1