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
너무 작기 때문에 다른 구현에서는 실패할 수 있습니다.
사용할 수 있습니다.z
size_t 및t
ptrdiff_t의 경우
printf("%zu %td", size, ptrdiff);
하지만 제 manpage에 따르면 오래된 도서관에는z
사용을 권장하지 않습니다.그러나 C99 표준에 따라 표준화되어 있습니다.그런 분들을 위해서intmax_t
그리고.int8_t
의stdint.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 printf
Linux, OS X 및 OpenBSD에서는 모두 지원 대상입니다.%z
위해서size_t
그리고.%t
위해서ptrdiff_t
(C99의 경우) 단, 그 중 어느 것도off_t
야생의 제안들은 보통 다음과 같은 것들을 제공합니다.%u
로의 변환.off_t
(양쪽 모두) "충분히 옳다"고 말할 수 있습니다.unsigned int
그리고.off_t
64비트 시스템과 32비트 시스템 간에 동일한 차이가 있습니다).
언급URL : https://stackoverflow.com/questions/586928/how-should-i-print-types-like-off-t-and-size-t
'programing' 카테고리의 다른 글
Firebase SnapShot.val()이 vuex의 데이터에 액세스하려고 할 때 null을 반환함 (0) | 2022.08.30 |
---|---|
String #equals 메서드와 String #contentEquals 메서드의 차이 (0) | 2022.08.30 |
(Vue, ChartJS) 하위 구성 요소 캔버스 컨텍스트에서 차트의 그라데이션 배경 생성 (0) | 2022.08.30 |
C, C99, ANSI C 및 GNU C의 차이점은 무엇입니까? (0) | 2022.08.30 |
이 인쇄물 "안녕하세요"는 어떻게 쓰여져 있나요? (0) | 2022.08.30 |