- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi folks
I feel like this should be a piece of cake, but I'm stumped.
I want to write over the values of an input text file for a particular line number in the file, and if possible a particular position on that line. Any suggestions?
Thanks!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In general writing in an existing file will destroy that file.
The simplest and most robust solution is to write a copy of the file, inserting/substituting
the new values as you go along.
If the file can be treated as a direct-access (formatted) file you can in fact overwrite
parts of it without damaging the rest. But that is a tricky route: it requires that all
records as viewed by the program have the same length (if you are stubborn enough,
I guess you could open the file with a record length of 1, thus allowing you to rewrite
the file at the smallest granularity).
Regards,
Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can write a copy of the input file no problem... but how do I replace specific, small parts of it, on various lines, with text from somewhere else. Each line contains multiple values corresponding with multiple parameters, but I only need to replace one value on a given line: how can I specify the position on the line to begin the write?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I understand it correctly, you want to replace a piece of a string by another piece?
Something along these lines:
character(len=80) :: string, value
string = "PARAMETER1 # Value of parameter 1"
write( value, '(f10.4)' ) 3.45
string(1:10) = value
write( 10, '(a)' ) string
This would produce a line:
3.45 # Value of parameter 1
Is this what you want?
Regards,
Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can write a copy of the input file no problem... but how do I replace specific, small parts of it, on various lines, with text from somewhere else. Each line contains multiple values corresponding with multiple parameters, but I only need to replace one value on a given line: how can I specify the position on the line to begin the write?
The level of file control you seek is straightforward, but mostly beyond the limited capabilities of Fortran file i/o (which is way behind the times, language-wise). If you are able to sacrifice portability for functionality, you can easily do all your file i/o using Win32 API functions which provide exactly the needed level of granular control. Here are some sample wrapper functions, which illustrate read/write operations wherein an arbitrary amount of data, denominated in bytes, can be positioned at any offset in the file:
[bash]SUBROUTINE rw_file (rwmode, ihandl, nbytes, loc_pointer, offset) IMPLICIT NONE CHARACTER(LEN=1), INTENT(IN) :: rwmode INTEGER(HANDLE), INTENT(IN) :: ihandl INTEGER, INTENT(IN) :: nbytes, loc_pointer INTEGER, INTENT(IN), OPTIONAL :: offset INTEGER :: nact ! position pointer if offset is provided IF (PRESENT(offset)) nact = SetFilePointer (ihandl, offset, NULL,FILE_BEGIN) IF (rwmode == 'R') THEN IF (.NOT.ReadFile (ihandl, & ! file handle loc_pointer, & ! address of data nbytes, & ! byte count to read LOC(nact), & ! actual bytes read NULL_OVERLAPPED)) THEN ! read error
END IF ELSE IF (.NOT.WriteFile(ihandl, & ! file handle loc_pointer, & ! address of data nbytes, & ! byte count to write LOC(nact), & ! actual bytes written NULL_OVERLAPPED)) THEN !write error
END IF END IF END SUBROUTINE rw_file SUBROUTINE Set_File_Pointer (ihandl, offset, truncate) IMPLICIT NONE INTEGER(HANDLE), INTENT(IN) :: ihandl INTEGER, INTENT(IN) :: offset LOGICAL, INTENT(IN), OPTIONAL :: truncate INTEGER :: rslt rslt = SetFilePointer (ihandl, MAX0(offset,0), NULL, FILE_BEGIN) IF (PRESENT(truncate)) rslt = SetEndOfFile (ihandl) END SUBROUTINE Set_File_Pointer [/bash]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Arjen, Paul - thanks for the assistance.
I originally began attempting this task in python, which I thought would be able to handle it without too much trouble. I have yet to get anywhere on this problem using python though.
That being said, I am obviously open to other options besides Fortran, though I frankly do not have the time to familiarize myself with another language right now - I have just spent three weeks trying to come to terms with DOS and BASH scripting as well as Python.
This is a link to the python forum I originally posted this question on - it contains the input file I am talking about as an attachment, and some conversation that clarifies just what I am trying to achieve.
http://www.daniweb.com/forums/post1120606.html#post1120606
I am very surprised by how seemingly difficult this is turning out to be - all I want is to be able to pinpoint a position in a text file, based on co-ordinates of line number and position on that line, and write the value of a variable over whatever is at that point.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"...all I want is to be able to pinpoint a position in a text file, based on co-ordinates of line number and position on that line, and write the value of a variable over whatever is at that point"
If each line (ie, record) in the file is the same length, presumably with a terminal
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am very surprised by how seemingly difficult this is turning out to be - all I want is to be able to pinpoint a position in a text file, based on co-ordinates of line number and position on that line, and write the value of a variable over whatever is at that point.
declare variables to hold a datarecord and a record count
initialise the record count to zero
open the input file
open the output file
read a record from the input file into the datarecord
did we get end-of-file?
If "yes" then go to "done"
increment record counter
is this the record, or one of the records, we wish to modify?
if "yes" then
find in the data record the specificsubstring we wish to modify
(hint use INDEX? unlessyou already knowthe start and length/end position of the substring)
replace the substring of datarecord containing that data with the new data
endif
write the datarecord to the output file
go back and read the next datarecord
"done"
close both files
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Streams ought to solve the issue of positioning the file pointer anywhere in the file,
but that does not make the problem as such much easier: files nowadays are mostly
seen as a sequence of bytes, not of lines. So the basic problem remains: figuring
out where in the file the change should be made.
Regards,
Arjen

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page