【问题标题】:What is wrong with printf("%llx")?printf("%llx") 有什么问题?
【发布时间】:2012-12-13 20:22:24
【问题描述】:

我的这段代码挑战了我所有的 C 知识。 我有:

int main(void){
    unsigned long long int massage ;

    scanf("%llX", &massage); //input: 0x1234567890abcdef
    printf("%llX", massage);
    return 0;
}

在我的“64bit - Corei5 - Fedora - GCC”上,它会准确地打印出我输入的内容。但在我好友的系统(32 位、MS XP、MinGW)上打印90ABCDEF。我不明白为什么。有人知道吗?

顺便说一句:sizeof(unsigned long long int) 在他的系统上是 8。

【问题讨论】:

  • 他在使用 MSVC 左右?它们具有非标准的 printfscanf 格式。应该可以在编译器的文档中找到。
  • 他使用 MINGW。 (编辑问题)
  • MinGW 是使用自己的 C 库,还是使用 Windows 库?在后一种情况下,非标准格式仍然适用。在前者,不知道。
  • @DanielFischer 相关:stackoverflow.com/questions/13590735/… 显然,它使用的是 Windows 的。

标签: c types platform-independent


【解决方案1】:

Windows C 库使用“%I64d”而不是“%lld”来打印 输入“long long”。

参考:http://gcc.gnu.org/ml/gcc-patches/2004-11/msg01966.html

【讨论】:

    【解决方案2】:

    问题是编译器所相信的(反映在sizeofsizeof(unsigned long long int) 在编译时评估)与运行时库相信的(反映在printf:@987654326)之间的差异@ 函数在运行时被调用,因此它的格式说明符生效)。

    根据"C99" in the MinGW documentation

    GCC 不包含 C 运行时库。这是平台提供的。 GCC 的 MinGW 端口使用 Microsoft 的原始(旧)Visual C 运行时 MSVCRT,它是 Microsoft Visual Studio 6(1998 年发布)的目标。

    […]

    因为 MinGW 依赖于 MSVCRT,它有许多与 Visual Studio 6 相同的限制和兼容性问题。您应该假设 MinGW 应用程序不能依赖 C99 行为,只能依赖 C89。例如,不支持 printf 中较新的格式字符,如 %a 和 %ll,尽管存在 workaround for %ll

    (它提到的解决方法是使用I64 而不是ll:所以,%I64X。令人讨厌的是,至少在我的系统上,GCC 会在看到文字格式字符串时发出警告,因为它假设它会有更好的运行时库。)

    【讨论】:

    • 您可以使用预处理器字符串连接来绕过 GCC 警告。它不会让你的代码看起来更好看,但至少它会为正确的库使用正确的代码。
    • @Tinctorius:解决警告并不是很难——例如,你可以将格式字符串存储在一个临时变量中——只是不得不这样做很烦人。 :-P
    • 让您的编译器检查您的格式字符串仍然很好。毕竟,格式字符串的正确性取决于printfscanf 的其他参数,所以在某种程度上,它是函数的一部分。您可以改为创建预处理器常量 HEX64,它转换为 "%I64X" 用于 MSVCRT 构建,"%llX" 用于类似 POSIX 的构建。然后你可以写printf("I like the number " HEX64 "!", number),GCC仍然可以检查number的类型是否与格式字符串一致。
    • @Tinctorius:抱歉,我认为我们的沟通有误。我的意思是——当我在一个带有 MinGW 的 Windows 系统上,并且我使用带有 %I64X 的文字字符串时,GCC 会给我一个警告消息,因为它不识别那个符号。它对运行时库一无所知,因此它假定为 POSIX-y。 (也就是说,GCC 的警告试图让我使用 POSIX 表示法,即使我在一个 POSIX 表示法不起作用的系统上。这是有道理的,但很烦人。)
    • 我明白了。然后是 GCC 的“错误”,因为它没有使这种检查易于扩展。或者实际上 MSVCRT 是一个糟糕的库。
    猜你喜欢
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多