please help !!

A

ayman daraghmah

FILE *input ;
char person[4][7];


int i;
input = fopen("salespersons.dat","r");
for(i=0;i<4;i++)
fscanf(input,"%s\n",person[7]);

for(i=0;i<4;i++)
printf("%s\n",person[7]);
return 0;
}




there's two warnings are :

13|warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char (*)[7]' [-Wformat]|




warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[7]' [-Wformat]|
 
J

Joe Pfeiffer

ayman daraghmah said:
FILE *input ;
char person[4][7];


int i;
input = fopen("salespersons.dat","r");
for(i=0;i<4;i++)
fscanf(input,"%s\n",person[7]);

for(i=0;i<4;i++)
printf("%s\n",person[7]);
return 0;
}




there's two warnings are :

13|warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char (*)[7]' [-Wformat]|


person[7] isn't the address of a string, it's a particular character
(and, in fact, it's the character one past the end of the buffer you
allocated). So you really wanted the address of the first element of
the string, or &person[0]

Something that's equivalent, and what most C programmers would write,
would be person
warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[7]' [-Wformat]|
 
J

James Kuyper

FILE *input ;
char person[4][7];


int i;
input = fopen("salespersons.dat","r");
for(i=0;i<4;i++)
fscanf(input,"%s\n",person[7]);


person[7] tries to retrieve the 8th char in the array person. That
array is only 7 characters long, so the behavior of your program is
undefined. That's just as serious an issue as the one your compiler
complains about - luckily, a single fix will correct both problems.
for(i=0;i<4;i++)
printf("%s\n",person[7]);
return 0;
}

there's two warnings are :

13|warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char (*)[7]' [-Wformat]|

warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[7]' [-Wformat]|


Both warnings are incorrect. In each case, the relevant argument has the
type 'char', which gets automatically promoted to an 'int'. However, the
fundamental problem is the same as the one the warnings warn about: the
type of the argument does not match the format specifier. person is
an lvalue of array type; like all such lvalues, it automatically gets
converted, in most circumstances, into a pointer to the first element of
the array. This is one of those circumstances. Since it's an array of
char, pointer has the type 'char*', which is precisely what you want.
Just drop the "[7]".
 
B

Ben Bacarisse

ayman daraghmah said:
FILE *input ;
char person[4][7];


int i;
input = fopen("salespersons.dat","r");
for(i=0;i<4;i++)
fscanf(input,"%s\n",person[7]);

for(i=0;i<4;i++)
printf("%s\n",person[7]);
return 0;
}


there's two warnings are :

13|warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char (*)[7]' [-Wformat]|

warning: format '%s' expects argument of type 'char *', but argument 2
has type 'char (*)[7]' [-Wformat]|


I don't think these warnings come from the code shown. No compiler I've
ever seen could be that wrong! You get these messages from gcc if you
write &person rather than person[7].

If the file is exactly as it should be, your use of fscanf is safe, but
sooner or later you will have to start learning how to protect your
program against rouge input.
 
I

Ike Naar

FILE *input ;
char person[4][7];

int i;
input = fopen("salespersons.dat","r");
for(i=0;i<4;i++)
fscanf(input,"%s\n",person[7]);

for(i=0;i<4;i++)
printf("%s\n",person[7]);
return 0;
}


In addition to the remarks that have already been made, here are
three more things you might want to pay attention to:

1)
In this program you allocate 7 characters for the name of each salesperson.
Each name is a null-terminated string and the null terminator has to be
stored as well, which leaves (at most) 6 useful characters for each name.
If you can be sure that the names in the input file are no longer than that,
the program, as written, is okay.
But if the names in the input file could be longer than 6 characters, you
will have to do something about the way you read the names, in order to
prevent fscanf from writing outside the bounds of the person array.

2)
Is there a reason why the format string for fscanf, "%s\n", has a newline
character after the "%s" conversion specifier? It will have the effect
that for each name fscanf will read (and discard) all trailing whitespace.
When reading from a file, this is not a big deal, but when reading from
an interactive source, such as a keyboard, this behaviour may
unpleasantly surprise the user who is typing the input.
Unless you have good reasons to add the "\n", it's better to drop
it and just use "%s" as the format string.

3)
It is always a good idea to check the return value of fscanf.
If a read fails for some reason, you can detect the fact.
If input failures go undetected, you may end up with garbage in the
person array without knowing that it contains garbage.
 
K

Keith Thompson

Ben Bacarisse said:
ayman daraghmah said:
FILE *input ;
char person[4][7];


int i;
input = fopen("salespersons.dat","r");
for(i=0;i<4;i++)
fscanf(input,"%s\n",person[7]);

for(i=0;i<4;i++)
printf("%s\n",person[7]);
return 0;
}


there's two warnings are :

13|warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char (*)[7]' [-Wformat]|

warning: format '%s' expects argument of type 'char *', but argument 2
has type 'char (*)[7]' [-Wformat]|


I don't think these warnings come from the code shown. No compiler I've
ever seen could be that wrong! You get these messages from gcc if you
write &person rather than person[7].


Right. The warnings I get for the OP's code are:

c.c: In function 'main':
c.c:11:9: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char (*)[7]' [-Wformat]
c.c:15:9: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[7]' [-Wformat]

`person[7]` is of type char, but it's implicitly converted to int
when passed to a variadic function.

ayman, please be sure to copy-and-paste the exact code you're compiling,
and the exact error messages you get when compiling that code.
If the file is exactly as it should be, your use of fscanf is safe, but
sooner or later you will have to start learning how to protect your
program against rouge input.

No, it isn't; he's passing a char value when a char* value is required.

(s/rouge/rogue/)
 
J

James Kuyper

Ben Bacarisse said:
ayman daraghmah said:
FILE *input ;
char person[4][7];


int i;
input = fopen("salespersons.dat","r");
for(i=0;i<4;i++)
fscanf(input,"%s\n",person[7]);

for(i=0;i<4;i++)
printf("%s\n",person[7]);
return 0;
}
....
Right. The warnings I get for the OP's code are:

c.c: In function 'main':
c.c:11:9: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char (*)[7]' [-Wformat]
c.c:15:9: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[7]' [-Wformat]


What compiler were you using, and with which options. With gcc and the
options I normally use, the message refers 'int', not 'char (*)[7]'.
 
B

Ben Bacarisse

Keith Thompson said:
If the file is exactly as it should be, your use of fscanf is safe, but
sooner or later you will have to start learning how to protect your
program against [rogue] input.

No, it isn't; he's passing a char value when a char* value is
required.

Of course. I meant when corrected.
 
K

Keith Thompson

James Kuyper said:
Ben Bacarisse said:
FILE *input ;
char person[4][7];


int i;
input = fopen("salespersons.dat","r");
for(i=0;i<4;i++)
fscanf(input,"%s\n",person[7]);

for(i=0;i<4;i++)
printf("%s\n",person[7]);
return 0;
}
...
Right. The warnings I get for the OP's code are:

c.c: In function 'main':
c.c:11:9: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char (*)[7]' [-Wformat]
c.c:15:9: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[7]' [-Wformat]


What compiler were you using, and with which options. With gcc and the
options I normally use, the message refers 'int', not 'char (*)[7]'.


My mistake; I mixed up the OP's code with a modified version of it.

With the OP's code the warnings refer to 'int'. To get the messages the
OP reported, referring to 'char (*)[7]', I had to change `person[7]`
to `&person`.

Obviously there's too much blood in my caffeine system today.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top