[comp.lang.c] Random Access files

TRM900@psuvm.psu.edu (Tony R. Marasco) (11/18/90)

Hello.  I am trying to use random access files and have run into some
problems...

I am using _fopen_ with a "w+b" parameter to create the file (if it doesn't
exist).  If it exists, I use "r+b".  Otherwise it seems to erase the file
like PASCAL's _rewrite_.  How am I doing so far??

I am also using _fseek_ to position the file pointer (recnum*size of struct)
with SEEK_SET.  I do this before each _fread_ & _fwrite_.  The program
seems to "lose" a few bytes at the beginning of each _fread_.

What is more astounding is I can write a record that doesn't exist, but
I can't update a record that already exists.

Any ideas?  Is it my fault or Turbo C's?

Any help is greatly appreciated.
-------
| Tony Marasco                 |  "Questions are a burden for others.     |
| Penn State University        |   Answers are a prison for oneself."     |
| Schuylkill Haven, PA 17976   |     - The Prisoner                       |
| trm900@psuvm.psu.edu       - or -   %s!psuvax1!psuvm.BITNET!trm900      |

gordon@osiris.cso.uiuc.edu (John Gordon) (11/20/90)

Tony R. Marasco <TRM900@psuvm.psu.edu> writes:

>Hello.  I am trying to use random access files and have run into some
>problems...

>I am using _fopen_ with a "w+b" parameter to create the file (if it doesn't
>exist).  If it exists, I use "r+b".  Otherwise it seems to erase the file
>like PASCAL's _rewrite_.  How am I doing so far??

	Opening a file in "w" mode is supposed to destroy existing files.  If
you don't want to do this, open in "a" mode.

>I am also using _fseek_ to position the file pointer (recnum*size of struct)
>with SEEK_SET.  I do this before each _fread_ & _fwrite_.  The program
>seems to "lose" a few bytes at the beginning of each _fread_.

	The first record number should be at recnum 0.  Are you starting at
recnum 1?


>What is more astounding is I can write a record that doesn't exist, but
>I can't update a record that already exists.

	I think that opening in "a" might work.

hp@vmars.tuwien.ac.at (Peter Holzer) (11/22/90)

gordon@osiris.cso.uiuc.edu (John Gordon) writes:

>Tony R. Marasco <TRM900@psuvm.psu.edu> writes:

>>Hello.  I am trying to use random access files and have run into some
>>problems...

>>I am using _fopen_ with a "w+b" parameter to create the file (if it doesn't
>>exist).  If it exists, I use "r+b".  Otherwise it seems to erase the file
>>like PASCAL's _rewrite_.  How am I doing so far??

>	Opening a file in "w" mode is supposed to destroy existing files.  If
>you don't want to do this, open in "a" mode.

But you would have to close it and reopen it with "r+" if you want to
modify existing records (see below). I doubt that 

	if ((fp = fopen (filename, "a+b")) == NULL) {
		/* error */
	} else {
		fclose (fp);
		if ((fp = fopen (filename, "r+b")) == NULL) {
			/* error */
		} else {
			/* everything ok */
		}
	}

is more elegant than

	if ((fp = fopen (filename, "r+b")) == NULL) {
		if ((fp = fopen (filename, "w+b")) == NULL) {
			/* error */
		} 
	}
	/* everything ok */

>>I am also using _fseek_ to position the file pointer (recnum*size of struct)
>>with SEEK_SET.  I do this before each _fread_ & _fwrite_.  The program
>>seems to "lose" a few bytes at the beginning of each _fread_.

>	The first record number should be at recnum 0.  Are you starting at
>recnum 1?

That would make no difference (except that he is wasting one record).

>>What is more astounding is I can write a record that doesn't exist, but
>>I can't update a record that already exists.

>	I think that opening in "a" might work.

No. Opening in "a" mode means that you cannot update existing records
but only append new ones (an lseek to the end of the file is done before
any write). In fact, the symptoms Tony describes sound exactly as if he
had opened the file in "a+" mode.
--
|    _  | Peter J. Holzer                       | Think of it   |
| |_|_) | Technical University Vienna           | as evolution  |
| | |   | Dept. for Real-Time Systems           | in action!    |
| __/   | hp@vmars.tuwien.ac.at                 |     Tony Rand |