[comp.sys.amiga.programmer] SAS C Bug?? Standard FILE command does not work!!

ben@epmooch.UUCP (Rev. Ben A. Mesander) (01/27/91)

>In article <1991Jan27.221835.1230@rodan.acs.syr.edu> goldberg@rodan.acs.syr.edu (Ross Goldberg) writes:
>I am trying to get a procedure working to read and write records to the
>disk.  This is accomplished in many books by using fwrite and fread.
>The sample below comes from one of the books...the problem is:
[...]
>#include <stdio.h>
>main ()
>{
> typedef struct {
>       char name[15];
>       int midterm;
>  } grades;
>int i,number;
>char name[50];
>grades student;
>FILE *fp;
>printf("class file  ");
>scanf("%s",name);
>if (NULL!=(fp=fopen(name,"w"))) {
>   printf("number of students");
>   scanf("%d",&number);
>   for (i=0;i<number;i=i+1) {
>     printf("student's name:  ");
>     scanf("%[^\n]",student.name);
>     printf("midterm score:  ");
>     scanf("%d",&(student.midterm));
>     fwrite (&student,sizeof(student),1,fp);
      ^^^^^^  ^^^^^^^^
>   }
[...]
>There is the book sample.
>As I said, where you see the fwrite (&student,sizeof(student),1,fp);
>it gives the warning for the &student    
>Ross Goldberg

From the Fine Manual for SAS/C:

SYNOPSIS

#include	<stdio.h>

a = fwrite(b,size,n,fp);

int	a;	actual number of blocks
char	*b;	pointer to first block
^^^^^^^^^^
int	bsize;	size of block in bytes
int	n;	maximum number of blocks
FILE	*fp;	file pointer

So, the first argument to fwrite needs to be a pointer to a character. 
You need to cast the pointer to your structure to a pointer to a character.
This is consistent with the definition of the C language, and is evidently
a bug in the program you typed in. Was the book pre-ANSI? I don't know,
my ancient UNIX reference manual lists the first argument to fwrite() as
a pointer to a character, so it's been that way for a very long time. 

Those books aren't perfect, you know!

--
| ben@epmooch.UUCP   (Ben Mesander)       | "Cash is more important than |
| ben%servalan.UUCP@uokmax.ecn.uoknor.edu |  your mother." - Al Shugart, |
| !chinet!uokmax!servalan!epmooch!ben     |  CEO, Seagate Technologies   |

goldberg@rodan.acs.syr.edu (Ross Goldberg) (01/28/91)

I am trying to get a procedure working to read and write records to the
disk.  This is accomplished in many books by using fwrite and fread.
The sample below comes from one of the books...the problem is:

On SAS C, the first argument in fwrite or fread which is &grades or something
like that in this case gives a warning 88:  argument type incorrect

This is standard C code so I am confused as to why SAS doesn't like it.
Any other ideas?  I tried using fscanf, but the problem there is that
a space ends reading in a string, and my strings my have 0, 1, or more
spaces in them.
The material being written in my case consists of 5 integers and 2 strings
(char arrays of [51] and [25] ) for however many entries there are.

anyway, here is the other one below.
(both mine and this give the same warning)
#include <stdio.h>
main ()
{
 typedef struct {
       char name[15];
       int midterm;
  } grades;
int i,number;
char name[50];
grades student;
FILE *fp;
printf("class file  ");
scanf("%s",name);
if (NULL!=(fp=fopen(name,"w"))) {
   printf("number of students");
   scanf("%d",&number);
   for (i=0;i<number;i=i+1) {
     printf("student's name:  ");
     scanf("%[^\n]",student.name);
     printf("midterm score:  ");
     scanf("%d",&(student.midterm));
     fwrite (&student,sizeof(student),1,fp);
   }
   fclose(fp);
} else
   printf("trouble opening the file\n");
}

There is the book sample.
As I said, where you see the fwrite (&student,sizeof(student),1,fp);
it gives the warning for the &student    
Ross Goldberg

tll@nntp-server.caltech.edu (Tal Lewis Lancaster) (01/29/91)

ben@epmooch.UUCP (Rev. Ben A. Mesander) writes:

>>In article <1991Jan27.221835.1230@rodan.acs.syr.edu> goldberg@rodan.acs.syr.edu (Ross Goldberg) writes:
>>I am trying to get a procedure working to read and write records to the
>>disk.  This is accomplished in many books by using fwrite and fread.
>>The sample below comes from one of the books...the problem is:
>[...]
>>#include <stdio.h>
>>main ()
>>{
>> typedef struct {
>>       char name[15];
>>       int midterm;
>>  } grades;
>>int i,number;
>>char name[50];
>>grades student;
>>FILE *fp;
>>printf("class file  ");
>>scanf("%s",name);
>>if (NULL!=(fp=fopen(name,"w"))) {
>>   printf("number of students");
>>   scanf("%d",&number);
>>   for (i=0;i<number;i=i+1) {
>>     printf("student's name:  ");
>>     scanf("%[^\n]",student.name);

This doesn't answer your problem with fwrite.  But it may interest you to
know that SAS's scanf doesn't support %[].

>>     printf("midterm score:  ");
>>     scanf("%d",&(student.midterm));
>>     fwrite (&student,sizeof(student),1,fp);
>      ^^^^^^  ^^^^^^^^
>>   }

[Rest deleted]

steve@wildcat.UUCP (Steve Holland) (01/30/91)

>In article <1991Jan27.221835.1230@rodan.acs.syr.edu> goldberg@rodan.acs.syr.edu (Ross Goldberg) writes:
>On SAS C, the first argument in fwrite or fread which is &grades or something
>like that in this case gives a warning 88:  argument type incorrect
>[Grades is a structure]

Yes this is a bug, but a very minor one. According to the ANSI definition
in K&R, fread/fwrite's first argument should be a "void *". Lattice/SAS
header files show it as a "char *". You can ignore the warnings,
use (char *)Grades instead of just Grades, or fix the bug yourself by
changing the Lattice/SAS header file to use a "void *" instead of a 
"char *". Since a pointer is a pointer, there is no effective difference
and this should not affect the compiler in any other way.

----------->Steve Holland<-----------
Internet: wildcat!steve@alfalfa.com  | "To err is human, but to really foul
USENET: ..bu!alphalpha!wildcat!steve |  things up requires a computer."
<if alfalfa doesn't work, try alphalpha>