delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/10/31/22:42:15

From: "John M. Aldrich" <fighteer AT cs DOT com>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Problems with fread/fwrite
Date: Thu, 31 Oct 1996 21:26:00 -0800
Organization: Three pounds of chaos and a pinch of salt
Lines: 168
Message-ID: <327989E8.170C@cs.com>
References: <Pine DOT LNX DOT 3 DOT 91 DOT 961101004806 DOT 67A-100000 AT warp DOT edu DOT ee>
Reply-To: fighteer AT cs DOT com
NNTP-Posting-Host: ppp211.cs.com
Mime-Version: 1.0
To: Indrek Mandre <indrek AT warp DOT edu DOT ee>
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

> #include <stdio.h>
> #include <stdlib.h>
> 
> struct proov {                          /* Little nice structure */
>         int mass[255];
>         int     z;
> };
> 
> void main()
> {
> struct proov *p, *t;
> FILE *fl;
> 
>  p = malloc ( sizeof ( struct proov ) );    /* Lets allocate memory */
>  t = malloc ( sizeof ( struct proov ) );
> 
>  fl = fopen ( "kace.aaa", "w" );            /* Lets write it to file */
>         p->z = 1999;                        /* Important ZZzzzz... */
>         fwrite ( p, sizeof ( struct proov ), 1, fl );
>  fclose (fl );
> 
>  fl = fopen ( "kace.aaa", "r" );            /* Lets read it */
>         fread ( t, sizeof ( struct proov ), 1, fl );
>  fclose (fl);
> 
>  printf("%d\n", t->z );                     /* It isn't 1999 */
>                                             /* 1/15 is 1999  */
> }
> 
>  On my machine t->z isn't at the end 1999! But on my Linux it
> works perfectly! Where is the problem? In my machine? Or should
> I use only open and read and write and will they work?
> I ran it in pure DOS box.
> 
> Another problem with fread/fwrite:
> 
> #include <stdio.h>
> #include <stdlib.h>
> 
> void main()
> {
>  FILE *fl;
>  char a[22000];
>  char b[2000];
> 
>  fl = fopen ( "kace.aaa", "w" );
>         fwrite ( a, 22000, 1, fl );     /* Created a file - 22000 bytes */
>  fclose ( fl );                         /* It's never so small - why?   */
> 
>  fl = fopen ( "kace.aaa", "r" );
>         printf("%d\n", fread ( b, 1, 1000, fl ));  /* Says here random  */
>         printf("%d\n", fread ( a, 1, 21000, fl )); /* Says here random  */
>  fclose (fl);
> 
> }
> 
> Again on Linux works (gcc 2.7.0).
> 
> Does fread/fwrite work? It isn't in my box :(
> Everything else seems to work perfectly, of course before I test it :)
> 
> Indrek Mandre
> indrek AT warp DOT edu DOT ee
> http://www.ttg.edu.ee/~indrek

The bugs are not in DJGPP, but rather in some wrong assumptions you are
making about the way memory and file handling is done in C.

Example 1:
  You should be opening the file in binary mode, not text mode (with "wb"/"rb"
  instead of "w"/"r").  Why?  Because DOS text uses a CRLF combination to
  denote end of line, while Unix/Linux only uses a CR.  You should never
  use fread()/fwrite() in conjunction with files in text mode.

Example 2:
  The same problem exists here as well.

The reason this problem is being triggered for you is because you are never 
initializing any of the variables you declare.  The ANSI spec makes no
guarantee that malloc'ed memory is zeroed, nor non-static local variables,
so when you do:

>  p = malloc ( sizeof ( struct proov ) );    /* Lets allocate memory */
>  t = malloc ( sizeof ( struct proov ) );

>  char a[22000];
>  char b[2000];

Because you never initialize them, p, t, a, and b all contain garbage.  Some
of this garbage likely has CR and EOF characters in it, which are passed
verbatim in binary mode, but are handled completely differently in text mode.
If EOF is present in any of that garbage, the text mode commands will think
that this denotes the end of the file, and stop reading at that point.

Try running under a debugger (gdb, edebug32, fsdb) and examine the contents
of those variables after you declare them.  You'll see what I mean.

Below I have attached fixed versions of your programs (note some other
things corrected as well).  Try these and see if they work; they do for me.

---- program 1 ----

#include <stdio.h>
#include <stdlib.h>

struct proov {                          /* Nice little structure */
        int mass[255];
        int     z;
};

int main( void )			/* THIS IS THE CORRECT WAY TO DECLARE MAIN */
{
static struct proov proov_zero;   	/* this will be initialized to zero because it's static */
struct proov *p, *t;
FILE *fl;

 p = malloc ( sizeof ( struct proov ) );    /* Let's allocate memory */
 t = malloc ( sizeof ( struct proov ) );

 *p = proov_zero;	/* copy zeroed structure */
 *t = proov_zero;

 fl = fopen ( "kace.aaa", "wb" );            /* Let's write it to a file */
        p->z = 1999;                        /* Important ZZzzzz... */
        fwrite ( p, sizeof ( struct proov ), 1, fl );
 fclose (fl );

 fl = fopen ( "kace.aaa", "rb" );            /* Let's read it */
        fread ( t, sizeof ( struct proov ), 1, fl );
 fclose (fl);

 printf("%d\n", t->z );

 return 0;
}

---- program 2 ----

#include <stdio.h>
#include <stdlib.h>

int main( void )		/* again, declare main right please */
{
 FILE *fl;
 char a[22000] = "";		/* define and initialize to all zeroes */
 char b[2000] = "";

 fl = fopen ( "kace.aaa", "wb" );
        fwrite ( a, 22000, 1, fl );     /* Created a file - 22000 bytes */
 fclose ( fl );

 fl = fopen ( "kace.aaa", "rb" );
        printf("%ld\n", fread ( b, 1, 1000, fl ));  	/* fread returns a long so use %ld */
        printf("%ld\n", fread ( a, 1, 21000, fl ));
 fclose (fl);

 return 0;
}

-- 
John M. Aldrich, aka Fighteer I <fighteer AT cs DOT com>

-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS d- s+:- a-->? c++>$ U@>++$ p>+ L>++ E>+ W++ N++ o+ K? w(---) O-
M-- V? PS+ PE Y+ PGP- t+(-) 5- X- R+ tv+() b+++ DI++ D++ G e(*)>++++
h!() !r !y+()
------END GEEK CODE BLOCK------

- Raw text -


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