Some background: If I wanted to use for, for instance, scanf() to convert a string into a standard integer type, like uint16_t, I’d use SCNu16 from <inttypes.h>, like this:
#include <stdio.h> #include <inttypes.h> uint16_t x; char *xs = '17'; sscanf(xs, '%' SCNu16, &x);
But a more uncommon integer type like pid_t does not have any such thing; only the normal integer types are supported by <inttypes.h>. To convert the other way, to portably printf() a pid_t, I can cast it to intmax_t and use PRIdMAX, like this:
#include <stdio.h> #include <inttypes.h> #include <sys/types.h> pid_t x = 17; printf('%' PRIdMAX, (intmax_t)x);
However, there does not seem to be a way to portably scanf() into a pid_t. So this is my question: How to do this portably?
#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! /*
I thought of scanf()ing to an intmax_t and then checking that the value is within pid_t’s limits before casting to pid_t, but there does not seem to be a way to get the maximum or minimum values for pid_t.
There is one robust and portable solution, which is to use
strtoimax()and check for overflows.That is, I parse an
intmax_t, check for an error fromstrtoimax(), and then also see if it ‘fits’ in apid_tby casting it and comparing it to the originalintmax_tvalue.It is not possible to use
scanf(), because, (as I said in a comment)scanf()will not detect overflows. But I was wrong in saying that none of thestrtoll()-related functions takes anintmax_t;strtoimax()does!It also will not work to use anything else than
strtoimax()unless you know the size of your integer type (pid_t, in this case).