uint32_t 및 size_t에 대한 printf 형식 지정자


101

나는 다음이있다

size_t   i = 0;
uint32_t k = 0;

printf("i [ %lu ] k [ %u ]\n", i, k);

컴파일 할 때 다음 경고가 표시됩니다.

format ‘%lu expects type long unsigned int’, but argument has type uint32_t

부목을 사용하여 이것을 실행했을 때 다음과 같은 결과를 얻었습니다.

Format argument 1 to printf (%u) expects unsigned int gets size_t: k

조언에 감사드립니다.


2
C89는 또는 uint32_t에서 지원하지 않습니다 . 이러한 유형을 사용하려면 C89로 업그레이드해야합니다. 확장 기능으로 GCC에서 사용할 수 있지만 C89에는 그러한 지원이 없습니다. <stdint.h><inttypes.h>
Jonathan Leffler

10
의 공식 C99 형식 수정자는에서 size_t와 같이 'z'입니다 "%zu".
Jonathan Leffler


@kenny의 대답이에 가장 적합하다고 생각 uint32_t하지만 부족 size_t합니다. @ u0b34a0f6ae의 대답에는 둘 다 포함됩니다.
jww

Jonathan Leffler의 첫 번째 의견에서 C89에 대한 두 번째 언급은 C99이어야합니다
bph

답변:


28

실제로 (32 비트) 인 경우 ( 64 비트) size_t와 동일 할 것으로 예상 하는 것처럼 들립니다 . 두 경우 모두 사용해보십시오 .unsigned longunsigned int%zu

그래도 확실하지는 않습니다.


1
컴파일 할 때 경고가 없습니다. 그러나 splint를 실행하면 다음과 같은 결과가 나타납니다. 1) printf (% u)는 unsigned int가 uint32_t를 가져올 것으로 예상합니다. i 2) printf (% u)는 unsigned int가 size_t를 가져올 것으로 예상됩니다. k
ant2009 2010

부목이 현학적 인 것 같군요. 아마도 소스 코드에서 유형의 이름을 벗어 났을 것이고 그것들이 동등하다는 것을 깨닫지 못합니다. @KennyTM의 대답으로 무엇을할지 궁금합니다 ... 확실히 더 이식성이 있어야합니다.
Cogwheel

3
부목은 실제로 옳은 일을하고 있습니다. 해서 int32_t될 일이 int컴파일러에서 / 플랫폼이되지 않을 수 있습니다 의미하지는 않습니다 long서로. 동일에 대한 size_t. 쉽고 자연스러운 검사는 컴파일러처럼 typedef를 존중하는 것이기 때문에 실제로는 길을 벗어나이 이식성 버그를 감지하기 위해 더 많은 작업을 수행하고 있습니다.
R .. GitHub STOP HELPING ICE

4
-1, 휴대가 안돼서 죄송합니다. 필요한 것은 형식 지정자와 유형이 일치하기 만하면되며 항상이를 사실로 만들기 위해 캐스팅 할 수 있습니다. long은 32 비트 이상이므로 %luwith (unsigned long)k는 항상 정확합니다. size_t까다롭기 때문에 %zuC99에 추가되었습니다. 그것을 사용할 수 없다면 k( longC89에서 가장 큰 유형이며 size_t더 클 가능성이 거의 없음) 처럼 취급하십시오 .
u0b34a0f6ae 2011

139

시험

#include <inttypes.h>
...

printf("i [ %zu ] k [ %"PRIu32" ]\n", i, k);

z동일 길이의 정수를 나타내고 size_t, 상기 PRIu32매크로 C99 헤더의 정의를inttypes.h , 부호없는 32 비트 정수를 나타낸다.


3
@robUK : 헤. 부목에 대한 버그를 제출하는 것이 좋습니다.
kennytm 2010

8
이것이 정답입니다. 내 개인적인 권장 사항은 단순히 캐스트하는 것 printf( "%lu", (unsigned long )i )입니다. 그렇지 않으면 나중에 유형 변경으로 인해 코드 전체에 경고 더미가 표시됩니다.
Dummy00001 2010-07-02

1
이것이 정답입니다. 부목에 대한 버그를 제출하는 것에 대해 KennyTM에 동의합니다. 그런데 "% zu"는 size_t에 적합한 형식입니다. size_t를 인쇄하기 위해 PRI * 매크로가 필요하지 않습니다.
R .. GitHub의 STOP 돕기 ICE

1
내가 정확하게 기억한다면 % zu는 C99이고 질문에서 그는 'C89'라고 썼습니다.
alcor

8
@alcor 예, 그는 C89 (분명히 그가 사용하고있는 gcc 컴파일러 플래그)를 넣었지만 uint32_t실제로는 C99 코드이므로 컴파일해야합니다.
Colin D Bennett

28

필요한 것은 형식 지정자와 유형이 일치하기 만하면되며 항상이를 사실로 만들기 위해 캐스팅 할 수 있습니다. long32 비트 이상이므로 %luwith (unsigned long)k는 항상 정확합니다.

uint32_t k;
printf("%lu\n", (unsigned long)k);

size_t까다롭기 때문에 %zuC99에 추가되었습니다. 그것을 사용할 수 없다면 k( longC89에서 가장 큰 유형이며 size_t더 클 가능성이 거의 없음) 처럼 취급하십시오 .

size_t sz;
printf("%zu\n", sz);  /* C99 version */
printf("%lu\n", (unsigned long)sz);  /* common C89 version */

전달하는 유형에 맞는 형식 지정자를 얻지 못하면 printf배열에서 메모리를 너무 많이 또는 너무 적게 읽는 것과 동일합니다. 유형을 일치시키기 위해 명시 적 캐스트를 사용하는 한 이식 가능합니다.


17

당신이 * 매크로를 PRI를 사용하지 않으려는 경우, 인쇄를위한 또 다른 방법 어떤 정수 유형으로 캐스트합니다 intmax_t또는 uintmax_t사용 "%jd"하거나 %ju, 각각. 이는 PRI * 매크로가 정의되지 않은 POSIX (또는 기타 OS) 유형에 특히 유용합니다 off_t.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.