5

I'm trying to find a way to replace a line, containing a string, in a file with a new line.

If the string is not present in the file, then append it to the file.

Can someone give a sample code?

EDIT : is there anyway if the line that i need to replace is at the end of the file?

Prasanth Madhavan
  • 12,657
  • 15
  • 62
  • 94
  • i have tried the appending part. and also creating a new file and moving the contents of the old file to the new file except the line to be deleted. But thats too tideous. I need somethin that is simple and elegent. :) – Prasanth Madhavan Dec 21 '10 at 12:17
  • 2
    http://stackoverflow.com/questions/2211749/c-file-programming-replace-a-text-in-a-file-using-posix-calls/2211761#2211761 – karlphillip Dec 21 '10 at 12:21
  • http://stackoverflow.com/questions/4100880/reading-and-appending-from-to-a-file-with-stdfstream – karlphillip Dec 21 '10 at 12:34
  • http://stackoverflow.com/questions/4007254/overwriting-data-in-a-c-file-using-fstream – karlphillip Dec 21 '10 at 12:34

4 Answers4

3

Although I recognize that this is not the smartest way to do it, the following code reads demo.txt line by line and searches for the word cactus to replace it for oranges while writing the output to a secondary file named result.txt.

Don't worry, I saved some work for you. Read the comment:

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

using namespace std;


int main()
{
  string search_string = "cactus";
  string replace_string = "oranges";
  string inbuf;
  fstream input_file("demo.txt", ios::in);
  ofstream output_file("result.txt");

  while (!input_file.eof())
  {
      getline(input_file, inbuf);

      int spot = inbuf.find(search_string);
      if(spot >= 0)
      {
         string tmpstring = inbuf.substr(0,spot);
         tmpstring += replace_string;
         tmpstring += inbuf.substr(spot+search_string.length(), inbuf.length());
         inbuf = tmpstring;
      }

      output_file << inbuf << endl;
  }

  //TODO: delete demo.txt and rename result.txt to demo.txt
  // to achieve the REPLACE effect.
}
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • thanks. What if all i needed was to replace the last 2 lines of a file completely with 2 new lines? – Prasanth Madhavan Dec 21 '10 at 12:49
  • @Prasanth Sounds like a new question to me. You could read the entire file once to discover how many lines of text are in it. Then subtract this value by 2 and you'll know which lines you should replace. Read the file again stopping on the interesting lines numbers and do your magic. – karlphillip Dec 21 '10 at 13:09
  • This sounded as a good snippet, but with VS 2010 I got totally wrong behaviour (no compiler error). My history included C and am no C++ wizard yet, so I discovered that the find method is not used in a standard way. See my snippet below. Wonder what the C++ wizards are saying here. I have found no better snippet than this on SE, what was quite surprising. – Philm Aug 20 '13 at 11:45
  • This doesn't check the state of `input_file` _after_ `getline`. [Why is `iostream::eof()` inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – Ted Lyngmo Dec 09 '20 at 06:30
  • @TedLyngmo Thanks! Feel free to adjust the code on this 10 years old answer if you think its worth. – karlphillip Dec 09 '20 at 13:35
1

As mentioned, the code by KarlPhilip is a good starting point (thanks), but did not work correctly according to the ">= 0". Comparing to "0" it is known for MS CString-types and in C#, etc, but it seems not to work properly with the STL. E.g. in VS 2010 (only release), the C++ code behaved wrong with this compare without throwing an error!

Here is a correction to C++ standards: If some wizards have improvements, please post them. I think, it is a very useful and important question/snippet.

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

using namespace std;    

int main() 
{   
   string search_string = "cactus";   
   string replace_string = "oranges";   
   string inbuf;
   // Todo: Check, if input_file exists before. 
   // Todo: Try/catch or check, if you have write access to the output file.
   fstream input_file("demo.txt", ios::in);   
   ofstream output_file("result.txt");

   while (!input_file.eof())   
   {
      getline(input_file, inbuf);
      size_t foundpos = inbuf.find(search_string);
      if(foundpos != std::string::npos)
      {
         string tmpstring = inbuf.substr(0,spot);
         tmpstring += replace_string;
         tmpstring += inbuf.substr(spot+search_string.length(), inbuf.length());
         inbuf = tmpstring;
      }

      output_file << inbuf << endl;   
   }

   //TODO: delete demo.txt and rename result.txt to demo.txt      
   // to achieve the REPLACE effect. 
}

I used the following replacement part inside the "if" from another SO question (The code above only replace the first occurrence):

if(foundpos != std::string::npos)
   replaceAll(inbuf, search_string, replace_string); 

//http://stackoverflow.com/questions/3418231/c-replace-part-of-a-string-with-another-string
//
void replaceAll(std::string& str, const std::string& from, const std::string& to) 
{
    size_t start_pos = 0;
    while((start_pos = str.find(from, start_pos)) != std::string::npos) 
    {
        size_t end_pos = start_pos + from.length();
        str.replace(start_pos, end_pos, to);
        start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
    }
}
Philm
  • 3,448
  • 1
  • 29
  • 28
1

To replace the last two lines in your file:

  • Use fopen() to open the file
  • Get the current file position with fgetpos()
  • Store always the last two file position and read line by line
  • When you've reached the end of the file: The lower position is where you have to position to with fseek()
  • Now you can fprintf() your new lines to the file and close it with fclose() afterwards.
ur.
  • 2,890
  • 1
  • 18
  • 21
0

If you want to change the length of (or delete) a line in the middle of a file, you will have to re-write all the subsequent lines.

There's no way of simply deleting or inserting characters into an existing file.

Roddy
  • 66,617
  • 42
  • 165
  • 277