背景知识:例如,如果我想用于scanf()将字符串转换为标准整数类型(例如uint16_t),则可以使用SCNu16中的<inttypes.h>,如下所示:

#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()可以!

除非您知道整数类型的大小(在这种情况下为strtoimax()),否则使用pid_t以外的任何方式也将不起作用。

10-06 15:55
查看更多