Click here to Skip to main content
14,696,627 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
So my problem is that I can't seem to figure out how to 'set tellp()' to the beginning of a particular line and then replace it with a new one. I've also just realised that I'm going to have to also figure out how to avoid writing over any of the next line too.. I should probably be able to figure that out though. This is what I've tried so far

std::fstream indiLine;
indiLine.open ("indiTest.mdl",std::ios::in | std::ios::out); //| std::ios::app);
if (indiLine.is_open())
{
   std::string inOut;
   int line_num = 0;
   //find line
   while (getline(indiLine,inOut))
   {
         if (line_num-1 == vNum) //stop at a particular line of text denoted by vNum
         {  std::cout << inOut << std::endl ;
            break; }
         line_num++;
   }
   indiLine.seekp(indiLine.tellg());
   indiLine << "R";
   indiLine.close();
}
else{ debugOut("Save Failure On Open",500); }


and the output for the particular lines I've tested:

Quote:
before subroutine;
X200Y200Z200E8D5
X-200Y200Z200E1D5
after subroutine;
X200Y200Z20RE8D5
X-200Y200ZR00E1D5

and those are the 8th and 9th lines when 'vNum' is at 5 and then 6 so they should be the 6th and 7th lines. Or rather those are the ones I'm after, in these particular instances.
so tellg() is giving me the wrong position.. If it was at the end of the line I could have just done something like
indiLine.seekp(indiLine.tellg-inOut.length());

but it's not so I don't really know what to do. Also it seems likely to me that I won't be able to just deduct an 'int' from the type that 'tellg()' returns.
Any hints on what to do to solve it this way would be really great and if I'm going at it from the completely wrong angle let me know what you have in mind, even better. Thanks guys, you're all awesome. :)
Posted
Updated 3-May-20 5:25am
Comments
Jochen Arndt 7-Nov-13 10:14am
   
Replacing lines in files can only be done when the replacement string has the same length as the line in the file. Otherwise you would overwrite content of the next line or have remaining characters. If you want to replace lines with different lengths, you have to read the file into memory, perform the replacement and write the new content back to the file.

After calling getline(), the position returned by tellg() points to the next line. To get the position for the begin of line, just store the previous position in a variable and use this for seeking (set the variable to 0 upon start and use tellg() as last command inside the loop).

1 solution

The most direct and relatively safe way of line editing a file is to:

Open your source file
Open a destination file
Read each line in turn from the source file:
- if it's not the correct line then write the line to the destination file
- if it's the line you want discard it and copy the new line to the destination file

Delete the source file
Rename the destination file

This has the advantage of not losing you any data if something goes horribly wrong! If it goes pear shaped an exception carries you out of the loop, everything gets closed and tidied up neatly. It can be a bit slow but personally I'll take a greater chance of being correct over fast any day.
   
Comments
James kingswell 7-Nov-13 11:47am
   
Thanks :) sounds perfect. How would I go about renaming the destination file? does fstream have the capability? what would I use? I haven't really used file storage much.. :/
Aescleal 7-Nov-13 11:59am
   
Streams don't know about files so I'd go for std::remove and std::rename, unless you've got access to boost::filesystem.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900