newbie read/write quesion

F

Frederik

Hi all,

I'm trying to do some C programming, but I need some help. I'm reading
a textfile [fread(...)]. When some sequence of characters is being
read, the file must not be read anymore, but instead I want to write
to it after those characters. How do I have to do this: Should I first
fclose the file and open it again or should I use read + write access?
And if I close the file first, how can I find the correct position
again where I left of? Is there a way to truncate the file? Many silly
questions I guess.

Thanks in advance,
Fre
 
W

Walter Roberson

:I'm trying to do some C programming, but I need some help. I'm reading
:a textfile [fread(...)]. When some sequence of characters is being
:read, the file must not be read anymore, but instead I want to write
:to it after those characters. How do I have to do this: Should I first
:fclose the file and open it again or should I use read + write access?

If you fclose() the file and fopen() it again, the file you get the
second time might not be the same file as the first time. Think of
deleting open files, and think of race conditions where someone renames
files while you are processing.

:And if I close the file first, how can I find the correct position
:again where I left of?

current_offset = lseek( fd, SEEK_CUR, 0);

Note that's a file descriptor; if you are using fopen()/fread() then
you may need to use fileno() to extract the fd.

:Is there a way to truncate the file?

ftruncate(fd, size)


In your situation, if getting that sequence of characters is expected
to be common, then I'd open for updates, do the processing,
lseek() to find out where you are, ftruncate() the file after
adjusting for any fiddling you have to do about the marker itself;
then lseek() to the end of file and start writing.

If getting the sequence of characters is not expected to be common,
then I would open for read only, and when the sequence was encountered,
I'd fdopen() to promote the read access into update access. That
done, lseek(), ftruncate(), lseek(), and write.

The second lseek() might look redundant, but when you ftruncate() the
file position is not well undefined, and when you switch from reading
to writing you must do an lseek() before you start writing [or
equivilent.] There are rules that have to be followed when you
transition from reading to writing or vice versas.
 
R

Raymond Martineau

Hi all,

I'm trying to do some C programming, but I need some help. I'm reading
a textfile [fread(...)]. When some sequence of characters is being
read, the file must not be read anymore, but instead I want to write
to it after those characters. How do I have to do this: Should I first
fclose the file and open it again or should I use read + write access?

It's generally better to use fopen("file", "r+") and keep it that way.
Given on what you want to do, there's less overhead in trying to keep track
of the current position.
And if I close the file first, how can I find the correct position
again where I left of?

Before you close the file, you can use one of the two following functions:
long ftell( FILE *stream );
int fgetpos( FILE *stream, fpos_t *pos );

After re-opening the file, you can use the following:
int fseek( FILE *stream, long offset, int origin );
int fsetpos( FILE *stream, const fpos_t *pos );

(If you're dealing with files >2GB, you probably should use fgetpos() and
fsetpos() instead.
Is there a way to truncate the file?

This is generally system specific:
http://www.eskimo.com/~scs/C-faq/q19.13.html
 
C

Christian Kandeler

Walter said:
:And if I close the file first, how can I find the correct position
:again where I left of?

current_offset = lseek( fd, SEEK_CUR, 0);

lseek() is not part of the C standard library. ftell()/fseek() is what the
OP is looking for.
Note that's a file descriptor; if you are using fopen()/fread() then
you may need to use fileno() to extract the fd.

fileno() also does not exist in ISO C.
:Is there a way to truncate the file?

ftruncate(fd, size)

Ditto.


Christian
 
E

Eric Sosman

Frederik said:
Hi all,

I'm trying to do some C programming, but I need some help. I'm reading
a textfile [fread(...)]. When some sequence of characters is being
read, the file must not be read anymore, but instead I want to write
to it after those characters. How do I have to do this: Should I first
fclose the file and open it again or should I use read + write access?
And if I close the file first, how can I find the correct position
again where I left of? Is there a way to truncate the file? Many silly
questions I guess.

Open with mode "r+" (or "rb+") instead of mere "r" ("rb").
When you've read as far as you want, fseek(fptr, 0, SEEK_CUR) --
this seems at first sight to be a no-op, but you must call a
positioning function when "reversing directions" from input to
output lest the implementation's internal buffers and suchlike
become confused. After the fseek(), start writing.

NOTE: This will not discard the pre-existing characters
that came after what you read, but will overwrite them. If
you don't overwrite all of them, the tail end of the the file
will still exist and still contain the original characters;
this sequence of operations does not truncate the file. For
example, if the file was originally 1000 characters long and
you read 100 characters and then overwrite 200 characters, the
result will be a file with three "zones:" 100 original characters
at the beginning, 200 new characters in the middle, and 700
original characters at the end.

If you want to get rid of those 700 trailing characters,
I can think of three possibilities:

- Instead of reading and then overwriting, read and copy
the first 100 characters to a new file and then write
200 characters to the new file. You can leave the old
file untouched, or you can fclose() both streams, delete()
the old file, and rename() the new to the old.

- If you know of a character (or sequence of characters)
that cannot possibly appear as data, write that character
or characters after the 200 new characters. All the
programs that read the file should treat this special
sequence as a pseudo-EOF. The <=699 trailing characters
will still be present in the file, but you'll ignore them.

- Use a non-Standard function to truncate the file, but be
aware that not all systems provide such functions and that
there may be subtle differences among systems that do.
 
C

Christian Kandeler

Eric said:
You can leave the old
file untouched, or you can fclose() both streams, delete()
the old file, and rename() the new to the old.

You probably meant to write remove() instead of delete().


Christian
 
F

Frederik

Thanks for your valuable answers.

I think I'm going for the closing/re-opening solution. When I open the
file in r+ mode, the process seems to slow down a little (not much
though).

Since the file data is overwritten, truncating becomes less a necessity.

Kinds regards,
Fre


:: Hi all,
:: I'm trying to do some C programming, but I need some help.
:: I'm reading
:: a textfile [fread(...)]. When some sequence of characters is being
:: read, the file must not be read anymore, but instead I want to write
:: to it after those characters. How do I have to do this:
:: Should I first
:: fclose the file and open it again or should I use
:: read + write access?
:: And if I close the file first, how can I find the correct position
:: again where I left of? Is there a way to truncate the file?
:: Many silly questions I guess.
:: Thanks in advance,
:: Fre
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,416
Latest member
LionelQ387

Latest Threads

Top