delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/12/11/05:28:22

Date: Thu, 11 Dec 1997 12:27:14 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: Mark Favata <favata AT epix DOT net>
cc: djgpp AT delorie DOT com
Subject: Re: Error Writing to File
In-Reply-To: <348EFB98.25F8@epix.net>
Message-ID: <Pine.SUN.3.91.971211122655.13672E-100000@is>
MIME-Version: 1.0

On Wed, 10 Dec 1997, Mark Favata wrote:

> The problem is, it keeps writing past the eof mark. 
> Within about 2 seconds it has already written 2 megs to the file.  My
> code doesn't seem to stop for the EOF.  Can you tell me what is wrong
> with my code?
> 
> This is like the code I am using:
> 
> if((in = fopen(argv[1], "rb+")) == NULL)
> {
>  printf("Error opening output file.\n");
>  exit(-1);
> }
> 
> while(!feof(in))
> {
>  fprintf(in, "0");
> }

feof' doesn't work when you write to a file, because you should be
able to expand the file by writing beyond its edge.  And that's
exactly what happens in your case.  If you want `feof' to work, you
need to read the file.

But reading and writing to the same file is tricky.  So I'd suggest to
change your program so it just writes the proper number of bytes
without reading the file: you can know the size of the file without
reading it.  Try the (untested) program below.  It might be not good
enough for very large (say, more than 2MB) files because it allocates
a buffer the size of the file, but you could allocate a smaller buffer
and overwrite such large files in several writes instead of one.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>

int main (int argc, char *argv[])
{
  if (argc > 1)
    {
      FILE *fp;
      struct stat st;
      off_t fsize;
      char *junk_buf = NULL;

      if (stat (argv[1], &st) == -1)
	{
	  perror (argv[1]);
	  return 1;
	}

      fsize = st.st_size;
      if ((junk_buf = (char *)malloc (fsize)) == NULL)
	{
	  perror ("memory exhausted");
	  return 2;
	}

      memset (junk_buf, 0, fsize);
      fwrite (junk_buf, 1, fsize, fp);
      return fclose (fp);
    }
  else
    {
      fprintf (stderr, "Usage: %s filename\n", argv[0]);
      return 0;
    }
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019