一些背景:例如,如果我想使用scanf()将一个字符串转换成一个标准的整数类型,就像uint16_t,我将使用< inttypes.h>中的SCNu16,像这样:
#include <stdio.h> #include <inttypes.h> uint16_t x; char *xs = "17"; sscanf(xs,"%" SCNu16,&x);
但是像pid_t这样一个更常见的整数类型没有这样的东西;只有正常的整数类型由< inttypes.h> ;.支持.要转换另一种方式,为了可移植的printf()一个pid_t,我可以将其转换为intmax_t并使用PRIdMAX,如下所示:
#include <stdio.h> #include <inttypes.h> #include <sys/types.h> pid_t x = 17; printf("%" PRIdMAX,(intmax_t)x);
然而,似乎没有办法将scanf()移植到pid_t中.所以这是我的问题:如何做这个可移植?
#include <stdio.h> #include <sys/types.h> pid_t x; char *xs = 17; sscanf(xs,"%u",&x); /* Not portable! pid_t might not be int! /*
我想到scanf()到intmax_t,然后在转换为pid_t之前检查该值是否在pid_t的限制内,但似乎没有办法获取pid_t的最大或最小值.
解决方法
有一个强大而便携的解决方案,它是使用strtoimax()并检查溢出.
也就是说,我解析一个intmax_t,检查一个来自strtoimax()的错误,然后再看一下它是否适合pid_t,并将其与原来的intmax_t值进行比较.
#include <inttypes.h> #include <stdio.h> #include <iso646.h> #include <sys/types.h> char *xs = "17"; /* The string to convert */ intmax_t xmax; char *tmp; pid_t x; /* Target variable */ errno = 0; xmax = strtoimax(xs,&tmp,10); if(errno != 0 or tmp == xs or *tmp != '\0' or xmax != (pid_t)xmax){ fprintf(stderr,"Bad PID!\n"); } else { x = (pid_t)xmax; ... }
不能使用scanf(),因为(正如我在评论中所说的)scanf()不会检测到溢出.但是我错了,说没有一个strtoll()相关函数需要一个intmax_t; strtoimax()做!
除了你知道你的整数类型的大小(在这种情况下是pid_t),它也不会使用除strtoimax()之外的任何东西.