#include #include 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\"
您可以在#include
之后添加以下内容:
#ifndef SCNd8 #define SCNd8 \"hhd\" #endif #ifndef SCNu8 #define SCNu8 \"hhu\" #endif
哪个适合大多数平台。
澄清:“大多数平台”指的是具有符合C99标准的fscanf
/ scanf
,可以处理char
的hh
前缀,而不仅仅是h
前缀。
有趣 – 我安装了GCC版本4.5.1的MinGW。
除了输入8位整数( SCNd8
和SCNu8
)之外, inttypes.h
的格式说明符宏大部分都SCNu8
。 这些宏在inttypes.h
中定义,但尝试使用它们并不能很好地工作。 使用以下代码:
#include #include int main(void) { int8_t int8 = 0; uint8_t uint8 = 0; scanf(\"%\"SCNd8, &int8); scanf(\"%\"SCNu8, &uint8); return 0; }
我收到以下警告:
C:temptest.c: In function \'main\': C:temptest.c:9:5: warning: unknown conversion type character \'h\' in format C:temptest.c:9:5: warning: too many arguments for format C:temptest.c:10:5: warning: unknown conversion type character \'h\' in format C:temptest.c:10:5: warning: too many arguments for format
所以似乎GCC 4.5.1和/或glibc不支持“%hhd”和“%hhu”C99格式说明符。 如果我在调试器下运行这个程序,那么不仅仅是字节变量最终会被scanf()
调用修改。
仅供参考,我使用以下命令进行编译:
\"C:MinGWbingcc\" -std=c99 -Wall -g -Ic:MinGWinclude -D_WIN32_WINNT=0x0500 \"C:temptest.c\" -lkernel32 -luser32 -lgdi32 -ladvapi32 -lshlwapi -loleaut32 -o \"test\".exe
请注意,如果指定了C99标准,则只能在inttypes.h
编译各种字符大小的int输入格式(使用“hh”) – 它们受以下内容保护:
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
即使对于C90编译,其他格式说明符也会编译。
所以你不会得到“hh”格式,除非你使用-std=c99
或-std=gnu99
选项(但请记住它们似乎无论如何都不起作用)。
更新:
当然! 不支持“hhd”和“hhu”说明符的原因是因为MinGW运行时使用来自Microsoft的msvcrt.dll
的scanf()
,它对C99的输入格式中的新内容一无所知。如果你想使用这些输入格式,您需要使用其他一些scanf()
实现。
正如MinGW的inttypes.h
所提到的:
MS运行时scanf似乎将“hh”视为“h”
SCN宏符合C99标准,因此出现了问题。 也许您必须使用-std=c99
进行编译。
如果您使用的是MinGW-w64,那么根据MinGW-w64 FAQ ,请使用以下define before includes
#define __USE_MINGW_ANSI_STDIO 1
这意味着使用MinGW-w64自己的stdio.h
实现,而不是推迟到不支持SCNu8
。 无论如何,这是一个好主意,因为Microsoft实现存在各种其他主要错误。
FAQ中有两个关于问题的条目,这里是另一个条目的链接 。
我使用gcc (x86_64-posix-sjlj-rev0, Built by MinGW-W64 project) 5.1.0
使用以下代码进行了测试
#include #include #include int main() { uint_fast8_t i = 0; scanf(\"%\" SCNuFAST8 \"n\", &i); printf(\"%\" PRIuFAST8 \"n\", i); return EXIT_SUCCESS; }
没有__USE_MINGW_ANSI_STDIO
,我得到了
ac: In function \'main\': ac:7:9: error: unknown conversion type character \'h\' in format [-Werror=format=] scanf(\"%\" SCNuFAST8 \"n\", &i); ^ ac:7:9: error: too many arguments for format [-Werror=format-extra-args]
我正在编译我的代码
>gcc -std=c11 -Wall -Werror ac
嗯……显然,“最新的gcc + MinGW + Netbeans + Windows”组合不提供兼容的C99编译器。
该标准专门将那些标识符记录在头文件
7.8整数类型的格式转换 […] 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
以上就是c/c++开发分享gcc(windows + MinGW)是否在inttypes.h中定义了SCNd8,SCNu8?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注(猴子技术宅)。