Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to replace a line inside a text file

Status
Not open for further replies.

ACS2013

Programmer
Feb 4, 2013
4
HK
I have a text file I want to replace the 2nd line with a different length of string. However, the result is the subsequent lines will be overwirte as the new line is longer than the old line.
How I can just replace exact the line I want, not touch the others?

My code is :
xFSO = CreateObject("Scripting.FileSystemObject")
*-- Loop until we get to the desired line
liLineNum=1
For i = 1 To liLineNum
=Fgets(liFile)
ENDFOR
liRc = Fputs(liFile, lsText)

Thanks for any idea!

 
Your code is a little confusing. You seem to be working with the FileSystemObject, and yet your are also using VFP low-level function, FGETS() and FPUTS(). These are two separate methods, and shouldn't be mixed.

That said, once you've decided which of the two methods you want to use, it should be a simple matter of slotting in a test for the second line. I won't try to write the entire code for you, but the following is an outline of what you want:

Code:
Open the input file for reading
Create a new file for output 
For each line in the input line
  If it's the second line
    Write the new contents to the output
  Else
    Write the input line to the output
  Endif
Endfor
Close the files
If necessary, copy the output file over the input file.
Hope this makes sense.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Why are you using xFSO = CreateObject("Scripting.FileSystemObject") ?
It does not seem to be used else where in your code.
Try this (untested)
Code:
lcfile =filetostr(myfile)
lnCount =alines(myarray,lcfile)
for i = 1 to lnCount
  if 'whatever' $ myarray[i]
    do something here
  endif
endfor

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
ReFox XI (www.mcrgsoftware.com)
 
If you know what text you want to replace and it is unique from other sections of text then, if it is in a file, you can use FILETOSTR(myFileName), delete the section of text with various functions such as STRTRAN() and then copying it back to the file with STRTOFILE(myEditedText, myFileName, OverwriteOrAppendFlag). If it isn't a file but is text in a memory variable string or a memo field, then it would be even simpler using just STRTRAN() and other search functions such as AT(), RAT(), etc. Your choice depends on the various factors involved such as how you would identify and locate your desired text to change or remove and how unique it is from the other sections.
 
Thank you for all you guys' suggestions, I have solved my problem. In fact, I am sorry that I paste some parts of wrong code and so make it a bit confusing. Anyway, your suggestions help me out.
 
Even though you have solved your problem, another simple way to replace text is to use the STUFF() function which can DELETE, REPLACE, or ADD text anywhere within another text file. STUFF() can be used to replace ANY text, whether the incoming text is shorter, the same length, or longer than the replaced text.

mmerlinn


Poor people do not hire employees. If you soak the rich, who are you going to work for?

"We've found by experience that people who are careless and sloppy writers are usually also careless and sloppy at thinking and coding. Answering questions for careless and sloppy thinkers is not rewarding." - Eric Raymond
 
Glad you could solve it.

There is no way to insert new text into a line of a file, you have to rewrite all. First of all filesystems handle file contents in blocks, no matter if they are binary or text files, there is no space unused to be able to stuff in something without overwriting following bytes. How should that work?

Just because FGETS reads a file line by line it doesn't mean the file is organised as lines array or collection. There is a very mechanical way behind this: FGETS just reads until the next LF char (13) or up to 8192 bytes. FPUTS also only writes to the end of a file, there is no concept of the "current line" you could write back to, there only is the concept of the current byte offset and FWRITE writes at that position, also you can position anywhere via FSEEK. But there is no way to let this shift all further content of a file automatically. Even if the new line would be shorter, there is no filesystem marking bytes as unused. So how should that really work? You expect too much.

Bye, Olaf.
 
mmerlinn,

STUFF works on a memory variable, not a file. You can do FILETOSTR(), STUFF() and STRTOFILE(), but you finally rewrite the whole file. You can overwrite file content via FWRITE, as said, but you can neither skip bytes, if the new text you want to write is shorter, nor add bytes, if the newly written bytes are more than you want to overwrite.

STUFF just uses a new memory segment, copies the left part of the old string, adds the new part, adds the right part of the old string, and lets the string variable point to that new memory address. STRTRAN does similar things repeatedly at each position a searched string is found. But there is no magic of allocating new bytes to add somewhere in the middle of an already allocated memory block or within a file block.

If you would need to stuff in something in the third line counted from the end of the file, it would be advisable to SEEK near to the end, read in the last lines, then FSEEK to the position where you need to overwrite and then just modify that part, after which you add the read in lines. But for the first or second line, a rewrite of the whole file is much easier, you always have to rewrite everything after the inserted line anyway.

That's also the reason the deletion of a row just marks the row deleted and doesn't remove it, that file modification would have the high cost to rewrite everything at the position of the removed record, and this cost is highest for the first lines or records.

The only way to make this as you want is to initially have enough bytes in the second line to put in your replacement line. Maybe you can at least modify or influence the initial file creation to generate a long enough line. And if you just can make it longer than needed, the best fit for the unused bytes would of course be spaces. The same way VFP pads unused bytes of a char field with spaces.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top