gcc(windows + MinGW)是否在inttypes.h中定义了SCNd8,SCNu8?

时间:2010-11-04 21:00:22

标签: c gcc mingw c99

#include <stdio.h>
#include <inttypes.h>

int main(void)
{
    int8_t int8;
    int16_t int16;
    int32_t int32;
    int64_t int64;

    uint8_t uint8;
    uint16_t uint16;
    uint32_t uint32;
    uint64_t uint64;

    scanf("%"SCNd8"%"SCNd16"%"SCNd32"%"SCNd64"%"SCNu8"%"SCNu16"%"SCNu32"%"SCNu64, 
            &int8, &int16, &int32, &int64, &uint8, &uint16, &uint32, &uint64);

    printf("%"PRId8"\n%"PRId16"\n%"PRId32"\n%"PRId64"\n%"PRIu8"\n%"PRIu16"\n%"PRIu32"\n%"PRIu64"\n",
            int8, int16, int32, int64, uint8, uint16, uint32, uint64);

    return 0;
}

我无法使用最新的gcc + MinGW + Netbeans + Windows编译此代码。 Netbeans说“无法解析标识符SCNd8和SCNu8”。我在gcc手册页上找不到SCNd8和SCNu8的任何参考,尽管http://linux.die.net/include/inttypes.h定义了它们。使用PRId8或PRIu8时,我没有收到语法错误。

MinGW inttypes.h(缺少SCNd8和SCNu8)(示例代码)

#define PRIXFAST64 "I64X"

#define PRIXMAX "I64X"
#define PRIXPTR "X"

/*
 *   fscanf macros for signed int types
 *   NOTE: if 32-bit int is used for int_fast8_t and int_fast16_t
 *   (see stdint.h, 7.18.1.3), FAST8 and FAST16 should have
 *   no length identifiers
 */

#define SCNd16 "hd"
#define SCNd32 "d"
#define SCNd64 "I64d"

#define SCNdLEAST16 "hd"
#define SCNdLEAST32 "d"
#define SCNdLEAST64 "I64d"

#define SCNdFAST16 "hd"    

6 个答案:

答案 0 :(得分:4)

您可以在#include <inttypes.h>之后添加以下内容:

#ifndef SCNd8
  #define SCNd8 "hhd"
#endif
#ifndef SCNu8
  #define SCNu8 "hhu"
#endif

哪个适用于大多数平台。

澄清: “大多数平台”指的是具有符合C99 fscanf / scanf的平台,可以处理hh的{​​{1}}前缀,而不仅仅是char前缀h

答案 1 :(得分:4)

有趣 - 我安装了GCC版本4.5.1的MinGW。

inttypes.h中的格式说明符宏大部分工作,但输入8位整数(SCNd8SCNu8除外)。这些宏在inttypes.h中定义,但尝试使用它们并不能很好地工作。使用以下代码:

#include <stdio.h>
#include <inttypes.h>

int main(void)
{
    int8_t int8 = 0;
    uint8_t uint8 = 0;

    scanf("%"SCNd8, &int8);
    scanf("%"SCNu8, &uint8);

    return 0;
}

我收到以下警告:

C:\temp\test.c: In function 'main':
C:\temp\test.c:9:5: warning: unknown conversion type character 'h' in format
C:\temp\test.c:9:5: warning: too many arguments for format
C:\temp\test.c:10:5: warning: unknown conversion type character 'h' in format
C:\temp\test.c:10:5: warning: too many arguments for format

因此,GCC 4.5.1和/或glibc似乎不支持“%hhd”和“%hhu”C99格式说明符。如果我在调试器下运行该程序,那么scanf()调用最终会修改字节变量 do

仅供参考,我使用以下命令进行编译:

 "C:\MinGW\bin\gcc" -std=c99 -Wall -g  -Ic:\MinGW\include -D_WIN32_WINNT=0x0500 "C:\temp\test.c"  -lkernel32 -luser32 -lgdi32 -ladvapi32 -lshlwapi -loleaut32 -o "test".exe

请注意,如果指定了C99标准,inttypes.h中的各种字符大小的int输入格式(使用“hh”)只会被编译 - 它们受以下内容保护:

#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L

即使对于C90编译,也会编译其他格式说明符。

除非您使用-std=c99-std=gnu99选项(但请记住它们似乎无法正常工作),否则您将无法获得“hh”格式。


更新

当然!不支持“hhd”和“hhu”说明符的原因是因为MinGW运行时使用来自Microsoft scanf()的{​​{1}},它对C99的输入格式中的新内容一无所知。如果您想使用这些输入格式,则需要使用其他msvcrt.dll实现。

如MinGW的scanf()

所述
  

MS runtime scanf似乎将“hh”视为“h”

答案 2 :(得分:1)

SCN宏符合C99标准,因此出现了问题。也许您必须使用-std=c99进行编译。

答案 3 :(得分:1)

如果您正在使用MinGW-w64,那么根据MinGW-w64 FAQ,使用以下定义包括

#define __USE_MINGW_ANSI_STDIO 1

这意味着使用MinGW-w64自己的stdio.h实现,而不是推迟到不支持SCNu8的Microsoft。无论如何,这是一个好主意,因为Microsoft实现存在各种其他主要错误。

常见问题解答中有两个关于问题的条目,这里是the link to the other one

我使用gcc (x86_64-posix-sjlj-rev0, Built by MinGW-W64 project) 5.1.0使用以下代码

对此进行了测试
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
  uint_fast8_t i = 0;
  scanf("%" SCNuFAST8 "\n", &i);
  printf("%" PRIuFAST8 "\n", i);
  return EXIT_SUCCESS;
}

没有__USE_MINGW_ANSI_STDIO,我得到了

a.c: In function 'main':
a.c:7:9: error: unknown conversion type character 'h' in format [-Werror=format=]
   scanf("%" SCNuFAST8 "\n", &i);
         ^
a.c:7:9: error: too many arguments for format [-Werror=format-extra-args]

我正在编译我的代码

>gcc -std=c11 -Wall -Werror a.c

答案 4 :(得分:0)

嗯......显然“最新的gcc + MinGW + Netbeans + Windows”组合不提供兼容的C99编译器。

该标准专门将标识符标识为标题<inttypes.h>

中定义的标识符
  

7.8整数类型的格式转换&lt; inttypes.h&gt;
  [...]
  7.8.1   [...]         [#4]有符号整数的fscanf宏是:

       SCNdN    SCNdLEASTN    SCNdFASTN     SCNdMAX    SCNdPTR
       SCNiN    SCNiLEASTN    SCNiFASTN     SCNiMAX    SCNiPTR

  [#5] The fscanf macros for unsigned integers are:

       SCNoN    SCNoLEASTN    SCNoFASTN     SCNoMAX    SCNoPTR
       SCNuN    SCNuLEASTN    SCNuFASTN     SCNuMAX    SCNuPTR
       SCNxN    SCNxLEASTN    SCNxFASTN     SCNxMAX    SCNxPTR

答案 5 :(得分:0)

我看到这是在MinGW-w64版本7的inttypes.h中定义的。 您可以从http://winlibs.com

使用此MinGW-w64版本获得GCC的构建。