更正 C 中自定义整数类型的格式说明符以确保可移植性

标签 c cross-platform portability

我想知道自定义整数类型(如 time_tsocklen_t 等)的正确 printf 格式说明符是什么。

例如,

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

int main()
{
    struct addrinfo *ai;

    if (getaddrinfo("localhost", "http", NULL, &ai) != 0) {
        printf("error\n");
        return EXIT_FAILURE;
    }

    printf("%d\n", ai->ai_addrlen);
}

虽然这个程序编译和运行良好,但我不喜欢使用 %d 来打印 ai_addrlen ,它被定义为类型 socklen_tstruct addrinfo 中,因为不能保证 socklen_tint 类型。

我们如何才能正确打印定义为 socklen_ttime_t 等的整数?我担心这里的可移植性。当程序在具有不同 socklen_t 定义的不同实现上编译时,我不必修改格式说明符。

最佳答案

intmax_t%jd 说明符使用中间转换:

printf("%jd\n", (intmax_t) ai->ai_addrlen);

强制转换将整数放大为能够表示任何其他有符号整数类型的值的最大可能大小的整数。这里有一个小警告:如果 sizeof(intmax_t) == sizeof ai->addrlenai->addrlen 是无符号的,大的值不适合有符号整数 (intmax_t) 将被截断。

如果您确定打印的类型是无符号的,请改用 uintmax_t%ju

j 字符是一个“长度子说明符”,特别适用于处理 intmax_t/uintmax_t 的大小,它可以放在一起使用 di 说明符字符(对于 intmax_t)或 uoXx 字符(对于 uintmax_t)。

关于更正 C 中自定义整数类型的格式说明符以确保可移植性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39417560/

相关文章:

将数字字符串转换为以二进制表示的字节数组

c - 如何从 ( C ) 中的另一个字符串获取子字符串

c++ - 从 C++ 应用程序发送验证电子邮件

c++ - 使用 snprintf() 的 Fencepost 条件和可移植性?

c - Valgrind 下的程序输出显着不同

java - 跨平台方式求用户的文档文件夹?

c# - 跨平台服务(通过c#客户端连接java服务)

java - 在 Windows 上用 Java 并发写入文件

sql - 可移植地确定字符串是否可转换为整数

c - 空指针的奇怪行为