3

I am using gcc 4.6.1 with mingw in windows.

I recently learned about the %a format specifier for representing floats exactly in floating-point hex notation (in C99, apparently).

For some reason I can print a float this way just fine, but I am having trouble scanning it.

If I replace both instances of %a, with %f my code handles printing and scanning the the floating point number just fine.

The code seems to work just fine when I ran it on a traditional Unix system (gcc 4.2.1).

I have tried every variation I could think of with floats and doubles. I tried adding the flag -std=c99, which seemed to change whether it treated the numeric literal as a double or float, but it did not fix my problem.

I want to know 2 things, if anyone else can duplicate this problem, and what I might do to fix it.

#include <stdio.h>
int main(){
    char buffer[1000];
    sprintf(buffer, "%la", 21.3930);

    double x = 0;
    printf("\n");
    printf(buffer);

    if(!sscanf(buffer, "%la", &x))
        printf("\nscan failed.");
    printf("\n%la", x);

    return 0;
}

The output is:

0x1.5649bap+4
scan failed.
0x0.000000p+0

Help would be greatly appreciated.

phuclv
  • 37,963
  • 15
  • 156
  • 475
derekmc
  • 161
  • 1
  • 7

1 Answers1

3

MinGW uses msvcrt.dll for the major part of its C runtime support. msvcrt.dll generally doesn't support C99 functionality.

There are some versions of MinGW that provide their own support for C99 I/O specifiers, but I haven't collected good information on exactly what versions support what C99 features.

See the following for some additional details:

Update: It looks like the TDM-64 distribution of MinGW (version 4.6.1) supports the C99 specifiers in the scanf() family of functions with prefixed names such as:

__mingw_sscanf()
__mingw_scanf()

It might be that support is improved in versions newer than 4.6.1 (it looks like that at least as of version 4.6.1 these functions are not in the 32-bit version of the TDM distribution - keep in mind that TDM-64 is capable of building 32-bit binaries as well as 64-bit binaries).

You can use a simple set of macros to 'redirect' the normal names to these functions.

Example output:

C:\temp>gcc --version
gcc (tdm64-1) 4.6.1

C:\temp>gcc -m32 -std=gnu99 -o test test.c

C:\temp>test

0xa.b24dd2f1a9fcp+1
0xa.b24dd2f1a9fcp+1
Community
  • 1
  • 1
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • Additionally, you can define `-D__USE_MINGW_ANSI_STDIO=1` when compiling and all functions that mingw has named as `__mingw_funcname()` will automatically be used by default. From here: https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/ – Purple Ice Nov 04 '18 at 20:04