gcc(windows + MinGW) 在 inttypes.h 中定义了 SCNd8、SCNu8 吗?

发布于 2024-09-30 09:02:26 字数 1430 浏览 9 评论 0原文

#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”。尽管 http://linux.die,但我在 gcc 手册页上找不到 SCNd8 和 SCNu8 的任何参考.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 <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;
}

I can't compile this code using latest gcc + MinGW + Netbeans + Windows. Netbeans says "unable to resolve identifier SCNd8 and SCNu8". I can't find any reference for SCNd8 and SCNu8 on gcc man page although http://linux.die.net/include/inttypes.h defines them. I don't receive syntax error for using PRId8 or PRIu8.

MinGW inttypes.h (lacks SCNd8 and SCNu8 ) (sample code)

#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"    

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

北笙凉宸 2024-10-07 09:02:26

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

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 格式说明符。如果我在调试器下运行此程序,do 最终会被 scanf() 调用修改。

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

 "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

请注意,inttypes.h 中的各种字符大小的 int 输入格式(使用“hh”)仅在符合 C99 标准时才会进行编译被指定 - 它们受到以下保护:

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

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

因此,除非使用 -std=c99-std=gnu99 选项,否则您不会获得“hh”格式(但请记住,它们似乎不起作用反正)。


更新:

当然!不支持“hhd”和“hhu”说明符的原因是 MinGW 运行时使用 Microsoft 的 msvcrt.dll 中的 scanf(),它不知道任何内容关于 C99 输入格式中的新内容 如果您想使用这些输入格式,则需要使用其他一些 scanf() 实现,

如 MinGW 的 inttypes.h 中所述 。代码>:

MS 运行时 scanf 似乎将“hh”视为“h”

Interesting - I have MinGW with GCC Version 4.5.1 installed.

The format specifier macros in inttypes.h work for the most part, except for the the ones for inputting 8-bit ints (SCNd8 and SCNu8). Those macros are defined in inttypes.h, but trying to use them doesn't work so well. With the following code:

#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;
}

I get the following warnings:

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

So it seems that GCC 4.5.1 and/or glibc don't support the "%hhd" and "%hhu" C99 format specifiers. If I run this program under a debugger, more than just the byte variables do end up being modified by the scanf() calls.

Just for reference, I'm using the following command to compile:

 "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

Note that the various character-sized int input formats (that use "hh") in inttypes.h only get compiled in if the C99 standard is specified - they're protected by:

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

The other format specifiers are compiled in even for C90 compiles.

So you won't get the "hh" formats unless you use the -std=c99 or -std=gnu99 options (but remember that they don't seem to work anyway).


Update:

Of course! The reason the "hhd" and "hhu' specifiers aren't supported is because the MinGW runtime uses the scanf() from Microsoft's msvcrt.dll which doesn't know anything about the new stuff in C99's input formats. If you want to use these input formats, you'll need to use some other scanf() implementation.

As mentioned in MinGW's inttypes.h:

MS runtime scanf appears to treat "hh" as "h"

音栖息无 2024-10-07 09:02:26

您可以在 #include 之后添加以下内容:

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

这应该适合大多数平台。

澄清:
其中“大多数平台”是指具有符合 C99 标准的 fscanf/scanf 的平台,可以处理 charhh 前缀code>,而不仅仅是 shorth 前缀。

You could add the following after #include <inttypes.h>:

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

Which should be appropriate for most platforms.

Clarification:
Where "most platforms" refers to platforms with a C99-compliant fscanf/scanf that can handle the hh prefix for char, not just the h prefix for short.

Saygoodbye 2024-10-07 09:02:26

如果您使用的是 MinGW-w64,则根据 MinGW-w64 FAQ< /a>,在包含之前使用以下定义

#define __USE_MINGW_ANSI_STDIO 1

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

常见问题解答中有两个关于该问题的条目,这里是 链接到另一个


我使用 gcc(x86_64-posix-sjlj-rev0,由 MinGW-W64 项目构建)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

If you are using MinGW-w64, then according to the MinGW-w64 FAQ, use the following define before includes

#define __USE_MINGW_ANSI_STDIO 1

That means to use MinGW-w64's own stdio.h implementation, instead of deferring to Microsoft's one which does not support SCNu8. This is a good idea anyway as the Microsoft implementation has various other major bugs.

There are two entries in the FAQ concerning the problem, here's the link to the other one.


I tested this using using gcc (x86_64-posix-sjlj-rev0, Built by MinGW-W64 project) 5.1.0 with the following code

#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;
}

Without the __USE_MINGW_ANSI_STDIO, I got

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]

I'm compiling my code like this

>gcc -std=c11 -Wall -Werror a.c
烂柯人 2024-10-07 09:02:26

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

The SCN macros are in the C99 standard, so something is going wrong. Perhaps you'd have to compile with -std=c99.

潇烟暮雨 2024-10-07 09:02:26

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

该标准专门记录了标头 中定义的那些标识符

7.8 整数类型的格式转换
[...]
7.8.1
[...]
[#4] 有符号整数的 fscanf 宏是:

<前><代码> SCNdN SCNdLEASTN SCNdFASTN SCNdMAX SCNdPTR
SCNiN SCNiLEASTN SCNiFASTN SCNiMAX SCNiPTR

[#5] 无符号整数的 fscanf 宏是:

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

Well ... apparently the combination "latest gcc + MinGW + Netbeans + Windows" does not provide a compliant C99 compiler.

The standard specifically documents those identifiers as being defined in the header <inttypes.h>

7.8 Format conversion of integer types <inttypes.h>
[...]
7.8.1
[...]
[#4] The fscanf macros for signed integers are:

       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
以酷 2024-10-07 09:02:26

我看到这是在 MinGW-w64 版本 7 的 inttypes.h 中定义的。
您可以从以下位置获取包含此 MinGW-w64 版本的 GCC 版本: http://winlibs.com

I see this is defined in inttypes.h in MinGW-w64 version 7.
You can get a build of GCC with this MinGW-w64 version from: http://winlibs.com

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文