programing

off_t, size_t 등의 인쇄 방법은 무엇입니까?

prostudy 2022. 8. 30. 21:34
반응형

off_t, size_t 등의 인쇄 방법은 무엇입니까?

다음과 같은 활자를 인쇄하려고 합니다.off_t그리고.size_t의 올바른 플레이스 홀더는 무엇입니까?printf() 휴대할 수 있습니까?

아니면 완전히 다른 방법으로 변수를 인쇄할 수 있을까요?

인쇄하다off_t:

printf("%jd\n", (intmax_t)x);

인쇄하다size_t:

printf("%zu\n", x);

인쇄하다ssize_t:

printf("%zd\n", x);

C99 표준의 7.19.6.1/7 또는 보다 편리한 포맷코드 POSIX 문서를 참조해 주세요.

http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html

사용하고 있는 실장이 이러한 포맷코드를 지원하지 않는 경우(예를 들어 C89를 사용하고 있기 때문에), AFIK에는 포맷코드를 가진 정수형이 없기 때문에 이러한 타입만큼 큰 것이 보증되어 있지 않기 때문에 약간 문제가 있습니다.따라서 구현 고유의 작업을 수행해야 합니다.

예를 들어, 컴파일러가 다음과 같은 경우long long표준 라이브러리가 지원하는%lld그 대신 사용할 수 있는 것은 자신 있게 기대할 수 있습니다.intmax_t하지만 만약 그렇지 않다면, 당신은 다시 로 돌아가야만 할 것이다.long너무 작기 때문에 다른 구현에서는 실패할 수 있습니다.

사용할 수 있습니다.zsize_t 및tptrdiff_t의 경우

printf("%zu %td", size, ptrdiff);

하지만 제 manpage에 따르면 오래된 도서관에는z사용을 권장하지 않습니다.그러나 C99 표준에 따라 표준화되어 있습니다.그런 분들을 위해서intmax_t그리고.int8_tstdint.h또 다른 답변과 같이 사용할 수 있는 매크로가 있습니다.

printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);

의 맨페이지에 기재되어 있습니다.inttypes.h.

개인적으로 저는 그냥 가치관을 던져주고 싶어요.unsigned long또는long다른 답변이 추천하는 것처럼요.C99 를 사용하는 경우는, 다음의 주소로 캐스트를 실시할 수 있습니다(물론 그래야 합니다).unsigned long long또는long long를 사용합니다.%llu또는%lld형식을 지정합니다.

C11 또는 C18을 사용하는 경우_Generic.

#include <stdio.h>
#include <sys/types.h>

    #define TYPE_FORMAT(variable) _Generic \
      (                                    \
        (variable)                         \
        , unsigned char       : "%hhu"     \
        , unsigned short      : "%hu"      \
        , unsigned int        : "%u"       \
        , unsigned long       : "%lu"      \
        , unsigned long long  : "%llu"     \
        , signed   char       : "%hhi"     \
        , signed   short      : "%hi"      \
        , signed   int        : "%i"       \
        , signed   long       : "%li"      \
        , signed   long long  : "%lli"     \
      )
      
      
int main(void)
  {
    off_t a=3321;
    printf(TYPE_FORMAT(a), a);
  }
      

단, 다음과 같은 큰 단점이 있습니다.이 방법으로는 문자열을 조합할 수 없습니다.의미는 다음과 같습니다.

printf("Foo: " TYPE_FORMAT(a), a);

동작하지 않기 때문에, 많은 상황에서 사용할 수 없게 됩니다.네, 실행 시 문자열을 조합할 수 있지만, 그것은 귀찮습니다.

내 기억으로는, 그것을 할 수 있는 유일한 휴대용 방법은 결과를 "서명되지 않은 긴 int"에 캐스팅하여 사용하는 것이다.%lu.

printf("sizeof(int) = %lu", (unsigned long) sizeof(int));

off_t. (8진수)에는 "%zo"를, 10진수에는 "%zu"를 사용합니다.

저는 이 글을 적어도 두 번 봤어요.왜냐하면 받아들여진 답변은 기억하기 어렵기 때문입니다(거의 사용하지 않습니다).z또는j플래그가 플랫폼에 의존하지 않는 처럼 보입니다.

표준에서는 정확한 데이터 길이가 명시되어 있지 않습니다.size_t그래서 먼저 길이를 체크하는 것이 좋습니다.size_t다음 중 하나를 선택합니다.

if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64

그리고 나는 그것을 사용하는 것을 추천한다.stdint즉, 일관성을 위해 원시 데이터 유형 대신 유형을 사용합니다.

Microsoft의 경우 답은 다릅니다.VS2013은 주로 C99를 준수하지만 "hh, j, z 및 t 길이의 접두사는 지원되지 않습니다."size_t "즉, 32비트 플랫폼에서는 서명되지 않은__int32, 64비트 플랫폼에서는 서명되지 않은_int64"에는 유형 지정자 o, u, x 또는 X를 가진 프리픽스 I(대문자 아이)를 사용합니다.VS2013 크기 사양 참조

off_t의 경우 VC\include\sys\types.h에 길게 정의되어 있습니다.

어떤 버전의 C를 사용하고 있습니까?

C90에서는 서명된 길이 또는 서명되지 않은 길이를 적절히 주조하고 그에 따라 인쇄하는 것이 표준 관행입니다.size_t에 대한 %z를 보았습니다만, Harbison과 Steel은 printf()에 기재되어 있지 않습니다.어쨌든 ptrdiff_t에 대해서는 도움이 되지 않습니다.

C99 에서는, 다양한 _t타입이 독자적인 printf 매크로와 함께 제공되기 때문에, 다음과 같은 것이 있습니다."Size is " FOO " bytes."자세한 것은 모릅니다만, 꽤 큰 숫자 형식의 include 파일입니다.

inttypes.h의 포맷 매크로를 사용합니다.

다음 질문을 참조하십시오. size_t형 변수의 크로스 플랫폼 형식 문자열?

을 살피는 것man 3 printfLinux, OS X 및 OpenBSD에서는 모두 지원 대상입니다.%z위해서size_t그리고.%t위해서ptrdiff_t(C99의 경우) 단, 그 중 어느 것도off_t야생의 제안들은 보통 다음과 같은 것들을 제공합니다.%u로의 변환.off_t(양쪽 모두) "충분히 옳다"고 말할 수 있습니다.unsigned int그리고.off_t64비트 시스템과 32비트 시스템 간에 동일한 차이가 있습니다).

언급URL : https://stackoverflow.com/questions/586928/how-should-i-print-types-like-off-t-and-size-t

반응형