uint64_t를 어떻게 인쇄합니까? "스퓨리어스 후미 '%'형식의 실패"


133

printf uint64_t의 매우 간단한 테스트 코드를 작성했습니다.

#include <inttypes.h>
#include <stdio.h>

int main()
{
  uint64_t ui64 = 90;
  printf("test uint64_t : %" PRIu64 "\n", ui64);
  return 0;
}

우분투 11.10 (64 비트) 및 gcc 버전 4.6.1을 사용하여 컴파일했지만 실패했습니다.

main.cpp: In function int main()’:
main.cpp:9:30: error: expected ‘)’ before PRIu64
main.cpp:9:47: warning: spurious trailing ‘%’ in format [-Wformat]

1
C 코드를 C ++로 컴파일하는 것 같습니다. 오류입니다. 파일 이름을 바꾸고 main.cgcc로 컴파일하면 모두 정상적으로 작동합니다.
Jens Gustedt


gcc 또는 clang을 사용 -std=c11하는 경우 사용중인 표준의 버전이나 버전 을 지정하는 것이 좋습니다 . 이것은이 오류와 다른 오류를 포착합니다. 나는 또한 -Wall -Wextra -Wpedantic -Wconversion적어도 추천 합니다.
Davislor

답변:


164

ISO C99 표준은 이러한 매크로가 명시 적으로 요청 된 경우에만 정의되도록 지정합니다.

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

... now PRIu64 will work

@Dan, 문제가 해결 된 경우 답변을 수락 된 것으로 표시 (왼쪽의 확인 표시 이미지 클릭)하는 것을 잊지 마십시오.
zneak

9
흠, 헤더 만 포함하면 충분합니다. __STDC_FORMAT_MACROS매크로은 C ++에 포함해야합니다.
Jens Gustedt

15
@Jens : 참으로; __STDC_FORMAT_MACROSC ++에서는 각주에만 C ++이 나타나며 C ++은 요청이있을 때만 이러한 매크로를 정의합니다. 그러나 C ++위원회는 제안을 무시하기로했다 . 특히 C 표준의 각주 182에 언급 된 __STDC_FORMAT_MACROS 기호는 C ++에서 아무런 역할을하지 않습니다. 따라서 컴파일러가 따라 잡을 때 __STDC_FORMAT_MACROSC 또는 C ++이 필요하지 않습니다 .
John Marshall

3
@John Marshall g ++ 4.7.3은 <inttypes.h>가 포함되어 있어도 매크로가 필요한 것 같습니다.
crockeea

4
@ 에릭 : 분명히 g ++ 4.7.3은 따라 잡히지 않았다! 실제로이 버그 수정 이전의 glibc 버전과 함께 사용하고있을 것입니다 . 해당 glibc 보고서에서 설명한 바와 같이 g ++ 4.7.3의 libstdc ++에는이 문제를 해결하는 코드가 있습니다. -std=c++0x<inttypes.h> 대신 #include <cinttypes>로 컴파일 하고 아마도 제공하지 않고 형식 매크로를 제공한다고 생각합니다 __STDC_FORMAT_MACROS.
John Marshall

4

Centos 5.xi에서 memcached를 컴파일 할 때 동일한 문제가 발생했습니다.

해결책은 gcc 및 g ++를 버전 4.4로 업그레이드하는 것입니다.

컴파일하기 전에 CC / CXX가 올바른 바이너리로 설정 (내보내기)되어 있는지 확인하십시오.


1

C ++ 태그를 포함 했으므로 {fmt} 라이브러리를 사용 하여 PRIu64매크로 및 기타 printf문제를 방지 할 수 있습니다 .

#include <fmt/core.h>

int main() {
  uint64_t ui64 = 90;
  fmt::print("test uint64_t : {}\n", ui64);
}

이 라이브러리를 기반으로하는 형식 지정 기능은 C ++ 20 : P0645의 표준화를 위해 제안되었습니다 .

면책 조항 : 저는 {fmt}의 저자입니다.


멋있는! 그것도 비슷한가 sscanf?
ceztko 2016

아마 가능합니다. 교체 가능성을 조사하고 scanf있습니다.
vitaut

큰! 또한 로케일 독립적 및 / 또는 로케일 선택 가능 버전으로 진행되는지 궁금합니다 std::to_string(). cppreference 페이지는 여전히으로 만 연결되며 std::to_chars()실제로 사람들에게 필요한 것은 아닙니다. fmt그리고 / 또는 c ++ 20이 아직 처리 하는지 궁금합니다 .
ceztko 2014

std::to_string아마도 그대로 유지되지만 std::format로케일 사용 여부를 제어 할 수 있습니다 (기본적으로 로케일을 사용하지 않음).
vitaut
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.