please help !!

Discussion in 'C Programming' started by ayman daraghmah, May 30, 2014.

  1. 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]|
     
    ayman daraghmah, May 30, 2014
    #1
    1. Advertisements

  2. ayman daraghmah

    Joe Pfeiffer Guest



    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
     
    Joe Pfeiffer, May 30, 2014
    #2
    1. Advertisements

  3. ayman daraghmah

    James Kuyper Guest



    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.


    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]".
     
    James Kuyper, May 30, 2014
    #3


  4. 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.
     
    Ben Bacarisse, May 30, 2014
    #4
  5. ayman daraghmah

    Ike Naar Guest



    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.
     
    Ike Naar, May 30, 2014
    #5


  6. 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.
    No, it isn't; he's passing a char value when a char* value is required.

    (s/rouge/rogue/)
     
    Keith Thompson, May 30, 2014
    #6
  7. ayman daraghmah

    James Kuyper Guest



    What compiler were you using, and with which options. With gcc and the
    options I normally use, the message refers 'int', not 'char (*)[7]'.
     
    James Kuyper, May 30, 2014
    #7
  8. Of course. I meant when corrected.
     
    Ben Bacarisse, May 30, 2014
    #8


  9. 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.
     
    Keith Thompson, May 30, 2014
    #9
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.