[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference hydra::amiga_v1

Title:AMIGA NOTES
Notice:Join us in the *NEW* conference - HYDRA::AMIGA_V2
Moderator:HYDRA::MOORE
Created:Sat Apr 26 1986
Last Modified:Wed Feb 05 1992
Last Successful Update:Fri Jun 06 1997
Number of topics:5378
Total number of notes:38326

4598.0. "C Program fwrite problem" by WELSWS::FINNIS () Tue Mar 19 1991 06:56

    Hi Guys,
    	I wonder if someone can shed some light on this problem.
    
    This program compiles fine on a VMS machine but when I try on the 
    amiga with Lattice 5.02 I get the following, and a blank part.fil
    

Compiling thu1.c
		fwrite (&part�3�rt, sizeof(part), 1, fptr);
                             ^
    
thu1.c 35 Warning 88: argument type incorrect
Module size P=000000A6 D=00000053 U=00000004

Total files: 1, Compiled OK: 1
    
    
    
    
    
    
/*thu1.c
   Write a program to prompt for and read from the terminal the values for
part name (maximum chars 10), part number (6 digits) and amount in stock.
Obtain and write 4 such records into a disk file using a structure.  
 */

#include <stdio.h>
/*	#include <local.h>	*/ 
int b;
main()
	{
	FILE *fptr;			/*pointer to file desc block*/
	struct	{			/*record in file for part*/
		char name[11];
		char number[7];
		short amount;
		}  part;
	short i;			/*count the parts - up to 4*/

	if ((fptr = fopen ("PART.FIL", "w")) == NULL)
		printf ("ERROR ON fopen\n"), exit (2);

	for (i=0 ; i<4 ; i++)
		{
		printf ("\nPart name:\t");	/*prompt*/
		scanf ("%s", part.name);

		printf ("\nPart number:\t");	/*prompt*/
		scanf ("%s", part.number);

		printf ("\nStock amt:\t");	/*prompt*/
		scanf ("%d", &part.amount);

		fwrite (&part, sizeof(part), 1, fptr);
		}
	fclose (fptr);
	}


    
T.RTitleUserPersonal
Name
DateLines
4598.1-OoopsWELSWS::FINNISTue Mar 19 1991 07:0010
    
    That should read 
		fwrite (&part, sizeof(part), 1, fptr);
    
    	Damm escape characters highlighting errors .. mumble.. mumble...
    
    
    			-Pete-
    
    
4598.2type castSTAR::GUINEAUbut what was the question?Tue Mar 19 1991 08:2313
> 
> 		fwrite (&part, sizeof(part), 1, fptr);

Try type casting the part variable. Lattice (SAS/C) is more Ansi compliant
than the VAX compiler. 

		fwrite((void *)&part, sizeof(part), 1, fptr);

Look in (I think) stdio.h for the prototype to see exactly what
LAttice expects for the "part" parameter's type.

john

4598.3Cast your cares away...WBC::BAKERWhatever happened to Fay Wray...Tue Mar 19 1991 10:4012
> 
> 		fwrite (&part, sizeof(part), 1, fptr);


	Cast it to a (char *), i.e.:

		fwrite((char *)&part, sizeof(part), 1, fptr);


	How much char would a char * *, if a char * could * char ?

	~art
4598.4Hey, VAX C can't be wrong all the timeTLE::RMEYERSRandy MeyersTue Mar 19 1991 14:0426
Re: .2

>Try type casting the part variable. Lattice (SAS/C) is more Ansi compliant
>than the VAX compiler. 

SAS C is more more ANSI C compliant in most things, but it looks like
they blew this one.

The function prototype for fwrite from the ANSI C standard is:

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

const void * is compatible with any pointer type.
size_t is compatible with any integer type.

So, the call in the program was correct.  No message was deserved.  No
casts are necessary.

I suspect that SAS C has a bad prototype in their headers.  (I suspect
that they have the first argument as char * instead of void *.)

My previous impression of the SAS C headers was that they needed a
lot of updating to be ANSI compliant.

By the way, VAX C does not complain about pointer type mismatches
in function calls unless you use the /STANDARD=PORTABLE qualifier.
4598.5MADRE::MWMTue Mar 19 1991 14:2312
>> My previous impression of the SAS C headers was that they needed a
>> lot of updating to be ANSI compliant.

The people at SAS agree with you. They've been saying that the 5.x version
predates the ANSI standard, and is only compliant if you don't look very
hard, especially at the headers. They're not planning on fixing the 5.x
version.

The 6.x version (currently in beta test) is being billed as the ANSI compliant
version of the compiler.

	<mike
4598.6Portable .. I tried..WELLIN::FINNISTue Mar 19 1991 15:4310
    I did compile it on the VMS system with /standard=portable.
    
    	This is why I was annoyed about the message .
    
    	I will try typecasting  to char etc. and post the results.
    
    
    Roll on V6.x that's what I say  :-)
    
    			-Pete-
4598.7Nearly There.....WELLIN::FINNISTue Mar 19 1991 16:247
    Well limited success.....
    
    Yes casting the fwrite to void or char did stop the Compiler 
    complaining, but the file PART.FIL still remained empty.
    	Again this does not happen on the VMS system.
    
    			Pete  :-( :-(
4598.8looks ok hereWHAMMY::spodarykdigging for fireWed Mar 20 1991 11:1514
I just tried this with SAS 5.1 and it looks fine.  The input was contained
in the file PART.FIL.  If you ^C out of the prompt loop, then those records may
not actually get written to the file, due to the RTL buffering I/O.

One thing to watch is that writing structures to a file via fwrite is not
portable.  Many compilers (esp RISC) will pad the structures so that fields
align properly (longs on longword boundries, etc).  Also note that DEC 
hardware uses little-endian for integers, where the Amiga uses big-endian.

Trying to move the binary file around to different systems will have limited
success, although the code itself may be "portable".  As pointed out previously
the safest bet is to output ASCII files and then fscanf the records back in.
 
Steve   
4598.9Did you change anything ?WELLIN::FINNISThu Mar 21 1991 04:5419
    Hi Steve,
    	Thanks for giving it a try on 5.10 .
    	Glad to hear it works Ok on that anyway, did you have to cast it
    as in previous notes , or did it work as is ?
    
    Would it be portable if I kept to ascii in the structure and used 
    fwrite, or is it something about the structure it does not like.
    
    
    I ran the program after casting the first argument to fwrite , but
    what should have gone to the file after the fourth record just got sent
    to the screen, and the file remained empty.!
    
    	Guess it's time to get the credit card out and upgrade to 5.10 .
    
    Is the IBM PC clone family (8086, 80286, 80386) little-endian or
    big-endian ?
    
    			-Pete-
4598.10KALI::PLOUFFAhhh... cider!Thu Mar 21 1991 09:341
    80X86 family is little-endian (just like VAX and DEC MIPS).
4598.11WHAMMY::spodarykdigging for fireThu Mar 21 1991 10:5323
Hi Pete,

     I did cast the fwrite((char *)&part, ...), as was suggested earlier.
That's to appease the function prototype.

     Using fwrite can be portable, but you have to make sure that 
the buffer that it's outputting is portable.  Two potential problems are
that different compilers will pad structure elements to align things properly
for their architecture.  Your part structure looks ok, but potentially the
name[] or number[] field could actually be larger than you've defined.
This may cause problems when reading the files on different machines.

     Another problem is that fwrite just writes bytes to the file, and
that integers are represented differently on different machines.  If
portability is an issue, perhaps a (or something like this):

fprintf(fptr, "%12s %8s %8d\n", part.name, part.number, part.amount)   

might work out better.  Then again, if portability isn't a concern, leave
it as it is - it works. 

Steve - not trying to turn this into the "portability"notefile :^)  I've been
        bitten with these things in the past, so I keep an eye out for them... 
4598.12It works !!!WELSWS::FINNISThu Mar 21 1991 14:0616
    
    	Well I finaly got it working.
    
    	The problem appeared to be the last scanf as %d this was corrupting
    the short in the structure . I tried it as %hd but to noavail.
    
    Anyway to cut a long story short (short being the operative word).
    
    I changed the declaration of amnt from short to int and cast the
    argument in fwrite to void and it worked fine..
    
    When you compiled with 5.10 what options did you use ?
    
    			_pete_  :-) :-)
    
    
4598.13Optimise !!!WELLIN::FINNISFri Mar 22 1991 14:528
    Things get more interesting....
    
    If you optimise the code ( with the short still in ) it works fine !
    
    lc -L -O file.c
    
    
    			-Pete-