Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中自定义整数类型的正确格式说明符以确保可移植性_C_Cross Platform_Portability - Fatal编程技术网

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

C中自定义整数类型的正确格式说明符以确保可移植性,c,cross-platform,portability,C,Cross Platform,Portability,我想知道对于自定义整数类型,如time\u t,socklen\u 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 ad

我想知道对于自定义整数类型,如
time\u t
socklen\u 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);
}
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
结构addrinfo*ai;
if(getaddrinfo(“localhost”、“http”、NULL和ai)!=0){
printf(“错误\n”);
返回退出失败;
}
printf(“%d\n”,ai->ai\u addrlen);
}
虽然该程序编译和运行良好,但我不喜欢使用
%d
打印
ai_addrlen
,它被定义为
struct addrinfo
中的
socklen\u t
类型,因为无法保证
socklen\u t
int
类型


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

使用中间转换来
intmax\u t
%jd
说明符:

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

如果您确定打印的类型没有签名,请改用
uintmax\t
%ju

j
字符是一个“长度子说明符”,特别适合处理
intmax\u t
/
uintmax\u t
的大小,它可以与
d
i
说明符(用于
intmax\u
)或
u
o
X
字符一起使用(对于
uintmax\t
)。

当已知类型的符号度时,答案是最佳方法

// if some unsigned type
printf("%ju\n", (uintmax_t) ux);

// if some signed type
printf("%jd\n", (intmax_t) x);
当不知道符号大小时,会发生质询。宏预处理不考虑类型。以下说明了符号大小问题。如果值仅可在
intmax\u t
uintmax\u t
中的一个中表示,则此方法非常有用

int main(void) {
  mystery_integer_type x = rand() - RAND_MAX/2;

  // Compiler can easily optimized one of the 2 paths out
  if (x * 0 - 1 > 0) {
    printf("Unigned %ju\n", (uintmax_t) x);
  } else {
    printf("Signed %jd\n", (intmax_t) x);
  }

}
请注意,如果类型小于
int/unsigned
,则所采用的路径将按照“…一个升级类型为有符号整数类型,另一个升级类型为相应的无符号整数类型,并且该值可在两种类型中表示;”C11dr§6.5.2.2 6


在尝试打印
时间时会出现一个特殊问题,C规范没有定义符号度,也没有定义它是整数还是浮点,只是它是实类型

对于极少数情况下需要便携式打印的
time\u t
,一些想法,从迂腐到随意

    // pedantic 
    printf("%La\n", (long double) time());
    printf("%.*Le\n", LDBL_DECIMAL_DIG - 1, (long double) time());
    printf("%.*e\n", DBL_DECIMAL_DIG - 1, (double) time());
    printf("%jd\n", (intmax_t) time());
    printf("%lld\n", (long long) time());
    printf("%ld\n", (long) time());
    // casual
注意:
time()
可能返回
(time)(-1)

(u)intmax\u t
和上述其他一些函数依赖于C99/C11。

C99之前版本的可移植性增加了未讨论的其他问题,通常导致使用
(长)
(双)

除了
大小
之外,任何其他标准(C、POSIX或其他)都没有特殊格式类型。您必须实际知道底层类型是什么。幸运的是,GCC和Clang非常擅长了解它,并且在使用错误的格式时会发出警告。不幸的是,如果您的代码必须在不同的平台上构建,并且具有不同大小的类型,那么这并没有真正的帮助。您没有显示
结构
,但是r
size\u t
您使用的是
printf(“%zu”,…)
@WeatherVane:
long
不能保证是可用的最大整数,尽管在大多数当前的实现中它是.C99明确定义的
intmax\u t
。@BlagovestBuyukliev我很抱歉,
intmax\u t
stdint.h
中,谢谢。@Joachim Pileborg“除了
size\u t
之外,对于任何其他标准的…类型都没有特殊的格式”。对于
ptrdiff\u t
宏,有
t
,例如
“td”
j
对于
(u)intmax\u t
。还有
SCN…
PRI…
宏,它们包含一些适用于这些类型的字符串。