문자열을 드문 정수 유형으로 포괄적으로 변환하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/437802

문제

배경 : 예를 들어 사용하고 싶다면 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() a 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()in 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,이 경우).

다른 팁

그것은 당신이 얼마나 휴대가되고 싶은지 정확히 달려 있습니다. Posix는 그렇게 말합니다 pid_t 프로세스 ID 및 프로세스 그룹 ID를 저장하는 데 사용되는 서명 된 정수 유형입니다. 실제로, 당신은 안전을 가정 할 수 있습니다 long 충분히 큽니다. 실패, 당신 intmax_t 충분히 커야합니다 (따라서 유효한 모든 것을 받아 들일 것입니다. pid_t); 문제는 그 유형이 합법적이지 않은 값을 받아 들일 수 있다는 것입니다. pid_t. 당신은 바위와 어려운 곳 사이에 갇혀 있습니다.

나는 사용할 것이다 long 그리고 100 년의 소프트웨어 고고학자가 512 비트 값을 pid_t.

POSIX 1003.1-2008 이제 웹에서 사용할 수 있습니다 (3872 페이지, PDF 및 HTML). 등록해야합니다 (무료). 나는 그것을 얻었다 열린 그룹 서점.

내가 보는 것은 서명 된 정수 유형이어야한다는 것입니다. 분명히, 모든 유효한 서명 된 정수 값이 적합합니다 intmax_t. 정보를 찾을 수 없습니다 <inttypes.h> 또는 <unistd.h> 이는 PID_T_MAX 또는 PID_T_MIN 또는 다른 값을 나타냅니다 (그러나 오늘 저녁에만 액세스 할 수 있었으므로 찾지 못한 곳에 숨어있을 수 있습니다). Otoh, 나는 나의 원래 의견을지지한다 - 나는 32 비트 값이 실용적으로 적절하다고 생각하며, 나는 long 어쨌든 8 비트 기계에서 64 비트가 될 것입니다. 나는 '적절한 특권'프로세스가 너무 큰 값을 읽고 유형의 불일치로 인해 잘못된 프로세스에 신호를 보냈다고 생각합니다. 나는 그것에 대해 걱정할 것이라고 확신하지 않습니다.

... OOOH! ... P400 아래 <sys/types.h>

구현은 blksize_t, pid_t, size_t, ssize_t 및 suseconds_t의 너비가 길이의 너비보다 크지 않은 하나 이상의 프로그래밍 환경을 지원해야합니다.

당신이 정말로 걱정한다면 당신은 할 수 있습니다 _assert(sizeof(pid_t) <= long) 또는 '%'물건에 대해 선택한 유형.

설명 된 바와 같이 이 답변, 사양이 말합니다 signed int. 'int'가 변경되면 정의에 따라 '%u'가 변경됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top