off_t 및 size_t와 같은 유형을 어떻게 인쇄해야합니까?


148

off_tand과 같은 유형을 인쇄하려고합니다 size_t. printf() 이식 가능한 올바른 자리 표시자는 무엇입니까 ?

아니면 변수를 인쇄하는 완전히 다른 방법이 있습니까?


2
@devin : Mac OS X fopen에서 fseek, 등 을 사용하는 동안 해당 유형을 발견했다고 생각 off_t합니다.
Georg Schölly

답변:


112

zsize_t와 tptrdiff_t에 사용할 수 있습니다 .

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

그러나 내 맨 페이지에 따르면 일부 오래된 라이브러리는 다른 문자를 사용했으며 z사용하지 않는 것이 좋습니다. 그럼에도 불구하고 (C99 표준에 의해) 표준화되었습니다. 분들 intmax_tint8_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


2
off_t는 실제로 내 시스템에서 오랫동안 서명되었습니다.
Georg Schölly

2
매뉴얼 페이지는 libc5에서 사용 된 Z (대문자) 사용을 권장하지 않습니다. z (소문자)를 실망시키지 않는 것 같습니다.
Draemon

12
부호 불일치 (C99 7.19.6.1 # 9)로 인해 %zda와 함께 사용 하는 size_t것은 정의되지 않은 동작 입니다. 이어야합니다 %zu.
Jens

7
그렇다면 off_t를 인쇄하는 방법은 무엇입니까?
JohnyTex

3
@Jens 나는 그 단락이나 다른 것에서 정의되지 않은 동작을 얻는 방법 %zd을 보지 못합니다 size_t. 실제로,의 정의 %z에 # 7의 명시 적 허용 %d하여 size_t상기 대응하는 서명 유형 및 값이 유효한 음수 값이 긴만큼 §6.2.5 # 9 명시 해당 서명 입력이 예상되는 부호 종류의 값을 사용하여 허용 서명 된 유형의
Chortos-2

108

인쇄하려면 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를 사용하기 때문에) AFAIK 이후 C89에는 형식 코드가 있고 정수가 큰 정수 유형이 없기 때문에 약간의 문제가 있습니다. 이 유형으로. 따라서 구현별로 무언가를 수행해야합니다.

예를 들어, 컴파일러에 long long표준 라이브러리 지원 기능이 %lld있다면이를 대신하여 사용할 수 intmax_t있습니다. 그러나 그렇지 않으면로 돌아 가야합니다 long. 너무 작기 때문에 다른 구현에서는 실패합니다.


3
이것은 훨씬 좋은 대답입니다. 부호없는 size_t에 % zu를 사용하는 것을 잊었을 것입니다. 그리고 intmax_t 로의 캐스트는 어떤 플랫폼에서든 off_t에 대한 훌륭한 솔루션입니다.
Peter Cordes

2
POSIX는 보장하지 않습니다 ssize_t와 같은 크기를 가지고 size_t있으므로 진정한 휴대용 코드로 변환해야 intmax_t와 함께 인쇄 %jd단지처럼 off_t.
nwellnhof

off_t는 크기가 길고 길어질 수 있으며 정의에 따라 달라질 수 있습니다 ... Visual Studio에서도 경고 "C4477 : '_snprintf_s': 형식 문자열 '% jd'에는 '__int64'형식의 인수가 필요하지만 가변 변수 1이 있습니다. 'off_t' "유형이 있습니다 ... 실제로 이식 가능한 방법은 printf ("% lld \ n ", (long long) x);
ericcurtin

5

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에 길게 정의되어 있습니다.


그렇다면 off_t항상 long32 비트가됩니다 (64 비트 Windows도 32 ​​비트를 사용합니다 long).
sourcejedi

3

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

C90에서 표준 관행은 서명 된 또는 서명되지 않은 long으로 적절하게 캐스트하고 그에 따라 인쇄하는 것입니다. size_t에 대해 % z를 보았지만 Harbison과 Steele은 printf ()에서 언급하지 않았으며 어쨌든 ptrdiff_t 또는 그 밖의 어떤 것에도 도움이되지 않습니다.

C99에서 다양한 _t 유형에는 자체 printf 매크로가 제공되므로 "Size is " FOO " bytes." 세부 사항을 알지 못하지만 상당히 큰 숫자 형식 포함 파일의 일부입니다.


3

inttypes.h의 포맷 매크로를 사용하고 싶을 것입니다.

이 질문을보십시오 : size_t 유형의 변수에 대한 플랫폼 간 형식 문자열?


off_t가 ptrdiff_t와 같이 서명 된 포인터 크기의 int (정확한 정의가 무엇인지 알 수 없음)라고 가정하면 PRIdPTR 또는 PRIiPTR을 사용합니다.
Michael Burr

11
off_t유형 (대부분의 32 비트 시스템이 일이다) 큰 파일을 지원하는 32 비트 시스템에 대한 포인터보다 크다.
Dietrich Epp

1
@DietrichEpp : 사실, 그것보다 더 나쁩니다. 많은 32 비트 시스템에는 off_t와 off64_t가 있으며 기능 매크로에 따라 off_t는 실제로 off64_t를 의미 할 수 있습니다.
SamB

1

보면 man 3 printf리눅스, OS X에, 모든 쇼에 대한 지원 오픈 BSD %z에 대한 size_t%t대한 ptrdiff_t(C99의 경우), 그러나 그 언급의 없음을 off_t. 야생의 제안은 일반적으로에 대한 %u변환을 제공합니다. off_t이는 내가 알 수있는 한 "충분히 정확합니다"( 64 비트와 32 비트 시스템 모두 동일 unsigned int하며 off_t다름).


1
내 시스템 (OS X)에는 32 비트 unsigned int및 64 비트가 off_t있습니다. 따라서 캐스트로 인해 데이터가 손실 될 수 있습니다.
Dietrich Epp

-3

허용 된 답변이 나를 위해 기억하기 어렵 기 때문에이 게시물을 두 번 이상 보았습니다 (나는 거의 사용하지 z않거나 j플래그를 지정하지 않으며 플랫폼에 독립적 이지 않습니다 ).

기준은 명확하게 정확한 데이터 길이라고 결코 size_t내가 먼저 길이를 확인해야합니다 제안, 그래서 size_t다음 중 하나를 선택하여 플랫폼 :

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

그리고 stdint일관성을 위해 원시 데이터 유형 대신 유형을 사용하는 것이 좋습니다 .


1
C99 및 C11의 경우 표준에 값 %zu을 인쇄하는 데 사용할 수있는 것이 명시되어 있습니다 size_t. 하나는해야 확실히 사용에 의존 uint32_t/ uint64_t를 인쇄하는 형식 지정자를 size_t그 유형이 호환된다는 보장이 없기로.
자폐증

-4

내가 기억하는 것처럼, 그것을 할 수있는 유일한 휴대용 방법은 결과를 "signed long int"로 캐스팅하고 사용하는 것 %lu입니다.

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

1
길이 수정자가 변환 전에 와야하므로 "% lu"여야합니다.
dwc

1
예를 들어 off_t는 부호있는 long long입니다.
Georg Schölly

@ GeorgSchölly- long longC ++ 표준에는 존재하지 않으므로 본질적으로 이식성이 없기 때문에 문제가 발생했습니다.
James Curran

-9

off_t에 "% zo"를 사용하십시오. (8 진수) 또는 10 %의 경우 "% zu"입니다.


왜 파일 오프셋을 8 진수로 하시겠습니까?
poolie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.