在Mingw-w64中使用%I64u会得到奇怪的结果

Getting weird result by using %I64u inside Mingw-w64

本文关键字:结果 Mingw-w64 %I64u      更新时间:2023-10-16

这是我的代码:

注意:\n内部扫描是我防止换行问题的方法。这不是最好的解决方案,但我用得太多了,现在已经成了我的习惯。:-)

...
int main()
{
    unsigned long long int input[2], calc_square;
    while(scanf("n%I64u %I64u", input[0], input[1]) == 2)
    {
        printf("%I64u %I64un", input[0], input[1]);
        ...

我预期的输入和程序结果是:

输入:

89 89

对于输出,它不打印回89,而是显示以下输出:

I64u I64u

我使用的是MSYS2软件包中的g++(GCC)4.9.1。注意g++,因为我的代码中有一些部分目前正在使用C++STL。


编辑:我使用标准的%llu而不是%I64u更改了代码,下面是我预期的输入和程序结果:

输入

89 89

对于输出来说,这是一个奇怪的结果:

25769968512 2337536

此代码错误:

while(scanf("n%I64u %I64u", input[0], input[1]) == 2)

input[0]input[1]各自具有类型unsigned long long,但对于scanf操作,它们需要具有类型unsigned long long *指向unsigned long long指针)。我不确定MinGW是否支持检查printfscanf格式说明符,但只要启用正确的警告,普通GCC就能够在编译时检测到这类错误。我强烈建议您始终使用尽可能高的警告级别进行编译,例如在最极端的情况下使用-Wall -Wextra -Werror -pedantic

您需要传入这些变量的地址

while(scanf("n%I64u %I64u", &input[0], &input[1]) == 2)
//                           ^          ^
//                           |          |

我怀疑您一直在使用MSYS2的GCC,它不是本机Windows编译器,也不支持特定于MS的%I64格式修饰符(MSYS2和Cygwin的GCC非常相似)。

如果您想使用MinGW-w64 GCC,您应该启动mingw64_shell.bat或mingw32_shell.bat,并安装适当的工具链:

pacman -S mingw-w64-i686-toolchain

pacman -S mingw-w64-x86_64-toolchain

完成后,您可以在任何Windows XP SP3版本上安全地使用任一修饰符,只要您传递-D_use_MINGW_ANSI_STDIO=1。

FWIW,我避免使用MS特定的修饰符,并始终通过-D_USE_MINGW_ANSI_STDIO=1

最后,令人恼火的是,当从MSYS2 shell启动时,您的示例不起作用,因为mintty不是一个合适的Windows控制台;您需要从cmd.exe 运行它