Thread: Compiler warning

  1. #1
    Registered User
    Join Date
    Jun 2016
    Posts
    3

    Compiler warning

    insert
    Code:
    FILE *fp=fopen("data00","r");
        if( ! fp )
        {
            printf("unable to open name of data00 file\n");
        }
    
    
        char *sName=NULL;
        char *sFile=NULL;
        int iLine=0;
        int iMatches=fscanf(fp,":%a[^:]:%a[^:]:%d:",&sName,&sFile,&iLine);
        if( 3 != iMatches )
        {
            printf("unable to do fscanf\n");
        }

    This code snippet gives me compiler warning saying :
    warning: format '%a' expects argument of type 'float *', but argument 3 has type 'char **' [-Wformat=]
    int iMatches=fscanf(fp,":%a[^:]:%a[^:]:%d:",&sName,&sFile,&iLine);
    ^
    warning: format '%a' expects argument of type 'float *', but argument 4 has type 'char **' [-Wformat=]

    How can I fix it?

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You can fix it by making sure you use the correct format specifier for the data you want to read in, and using the correct variable for that format specifier . Yes, that is a bit of a smart-a$$ response, but learning to find, read and comprehend technical documentation is a critical skill for any programmer, even the hobbyist.

    From the scanf documentation:
    Quote Originally Posted by scanf documentation
    f
    Matches an optionally signed floating-point number; the next pointer must be a pointer to float.

    a
    (C99) Equivalent to f.

    s
    Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null byte ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.

    c
    Matches a sequence of characters whose length is specified by the maximum field width (default 1); the next pointer must be a pointer to char, and there must be enough room for all the characters (no terminating null byte is added). The usual skip of leading white space is suppressed. To skip white space first, use an explicit space in the format.

    [
    Matches a nonempty sequence of characters from the specified set of accepted characters; the next pointer must be a pointer to char, and there must be enough room for all the characters in the string, plus a terminating null byte. The usual skip of leading white space is suppressed. The string is to be made up of characters in (or not in) a particular set; the set is defined by the characters between the open bracket [ character and a close bracket ] character. The set excludes those characters if the first character after the open bracket is a circumflex (^). To include a close bracket in the set, make it the first character after the open bracket or the circumflex; any other position will end the set. The hyphen character - is also special; when placed between two other characters, it adds all intervening characters to the set. To include a hyphen, make it the last character before the final close bracket. For instance, [^]0-9-] means the set "everything except close bracket, zero through nine, and hyphen". The string ends with the appearance of a character not in the (or, with a circumflex, in) set or when the field width runs out.
    fscanf saw %a and assumed you were trying to scan in a float. You did not provide the necessary variable type for %a (pointer to float).

    It appears (from your variables sName and sFile) you want to read in strings. Thus, you would use a string/character modifier. That would be %[ in your case because you want to stop at a colon (%s only stops at whitespace). If you're using [^:], you can not also use another character (like a, c or s) between it and the percent sign1. So you want %[^:], which means "match any characters up to the first colon".

    There are a few more problems:

    1. %[ expects the argument to be a pointer to char. sName and sFile are already pointers to char. If you put an & in front of them, you get a pointer to pointer to char, which is the wrong type. When you want scanf to store data in a string with %s or %[, you typically don't need the & since it's already a pointer.
    2. You don't actually allocate memory to store what you scan. You set sName and sFile to NULL; you need to provide some memory to store the string it scans. Try something like char sName[100], or whatever size is appropriate.
    3. You check if fopen fails and print a message. But then, you continue on anyway with a null file pointer! This means any file operation will operate on a null pointer and result in undefined behavior (probably a seg fault). If you can't open the file, print your message and exit the funciton/program immediately -- you can not go on from there.



    1 There are some exceptions -- read the documentation for more info.

  3. #3
    Registered User
    Join Date
    Jun 2016
    Posts
    3

    Thanks,

    I tried using %[^:] instead of %a[^:] which gives me this error now:

    warning: format '%[^:' expects argument of type 'char *', but argument 3 has type 'char **' [-Wformat=]
    int iMatches=fscanf(fp,":%[^:]:%[^:]:%d:",&sName,&sFile,&iLine);
    ^
    warning: format '%[^:' expects argument of type 'char *', but argument 4 has type 'char **' [-Wformat=]

    Thanks,
    Madhavi Sinha

  4. #4
    Tweaking master Aslaville's Avatar
    Join Date
    Sep 2012
    Location
    Rogueport
    Posts
    528
    Quote Originally Posted by Madhavi View Post
    warning: format '%[^:' expects argument of type 'char *', but argument 3 has type 'char **' [-Wformat=]
    int iMatches=fscanf(fp,":%[^:]:%[^:]:%d:",&sName,&sFile,&iLine);
    ^
    warning: format '%[^:' expects argument of type 'char *', but argument 4 has type 'char **' [-Wformat=]
    That's right!

    fscanf expects pointer to a string _not_ the address of a pointer.

    You need something like

    Code:
            /* passing the pointer */
        int iMatches=fscanf(fp,":%a[^:]:%a[^:]:%d:",sName, sFile,&iLine);
    
             /* passing the address of a pointer (wrong) */
        int iMatches=fscanf(fp,":%a[^:]:%a[^:]:%d:",&sName, &sFile,&iLine);

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Aslaville is right -- except he used the broken version with an extraneous a in the format specifier -- but it would be helpful if you showed your updated code.

    The issue you are having is addressed by items 1 and 2 in my "a few more problems" section. You must make sure you are also allocating memory to store what fscanf reads in.

    If you're still stuck, please post your updated code.

  6. #6
    Registered User
    Join Date
    Jun 2016
    Posts
    3
    Hi anduril,

    I am still stuck, Please help.
    the data00 file has :
    :testing:testing.c:2481:

    My updated code is :
    Code:
    FILE *fp=fopen("data00","r");
        if( ! fp )
        {
            //RED_ERR("unable to open name of locker file\n");
            printf("unable to open name of locker file\n");
        }
        char buffer[256];
        char *sName= buffer;
        char *sFile= buffer;
    
    
        int iLine=0;
        int iMatches=fscanf(fp,":%a[^:]:%a[^:]:%d:",&sName,&sFile,iLine);
        if( 3 != iMatches )
        {
        	printf("unable to do fscanf\n");
        }
    
    
        fclose(fp);
    The build environment was earlier using gcc -C99 but they removed C99 file that is the reason I am getting the warning?

  7. #7
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,106
    @ Madhavi
    The build environment was earlier using gcc -C99 but they removed C99 file that is the reason I am getting the warning?
    Code:
    $ gcc -Wall -Wextra -pedantic -std=C99 -o testing testing.c
    Including other options or .c files as needed

    EDIT: What version of gcc are you running?
    Last edited by rstanley; 06-09-2016 at 08:33 AM.

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You need to exit the function/program if you can't open the file:
    Code:
    FILE *fp=fopen("data00","r");
        if( ! fp )
        {
            //RED_ERR("unable to open name of locker file\n");
            printf("unable to open name of locker file\n");
            // if you don't return from the function or exit the program, then your program will try to read
            // from fp, which is invalid, and the program will likely crash
        }
    sName and sLine can't point to the same buffer. Just declare them each as their own array/buffer, like so:
    Code:
    char sLine[256];
    char sName[256];
    You can not use %a[. That is invalid. You just want %[, so
    Code:
    fscanf(fp, ":%[^:]:%[^:]:%d", sName, sName, iLine);
    Note that there is no a in there. There is also no & in front of sName. sFile should be just like sName: no a and no &. iLine is fine the way it is.

    Regarding C99: this shouldn't matter once you get rid of the a from your format specifier.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    If you're stuck with C89, then you'll also need to move some of your variable declarations to earlier in the function.

    C89 doesn't allow declarations and code to be mixed.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. gcc compiler warning
    By matrixx333 in forum C Programming
    Replies: 4
    Last Post: 07-14-2010, 04:43 AM
  2. Compiler Warning
    By samuelmoneill in forum C Programming
    Replies: 5
    Last Post: 04-16-2009, 06:57 AM
  3. Compiler warning
    By drnaphtali in forum C Programming
    Replies: 2
    Last Post: 11-07-2008, 11:16 AM
  4. compiler warning still won't go away
    By trprince in forum C Programming
    Replies: 1
    Last Post: 11-30-2007, 08:35 PM
  5. Why compiler warning?
    By cdave in forum C Programming
    Replies: 16
    Last Post: 09-06-2004, 01:03 AM

Tags for this Thread