printf를 사용하여 부호없는 long long int를 어떻게 포맷합니까?


379
#include <stdio.h>
int main() {
    unsigned long long int num = 285212672; //FYI: fits in 29 bits
    int normalInt = 5;
    printf("My number is %d bytes wide and its value is %ul. A normal number is %d.\n", sizeof(num), num, normalInt);
    return 0;
}

산출:

My number is 8 bytes wide and its value is 285212672l. A normal number is 0.

이 예기치 않은 결과는를 인쇄 한 것으로 가정합니다 unsigned long long int. 당신이 어떻게 할 printf()에게 unsigned long long int?


2
방금 gcc로 코드 (% llu 포함)를 컴파일했으며 출력이 올바른 것입니다. 컴파일러에 옵션을 전달하고 있습니까?
Juan

2
samsung bada의 newlib는 "% lld"를 지원하지 않는 것 같습니다 : developer.bada.com/forum/…
RzR


stdint.h를 사용하고 변수의 비트 수에 대해 명시 적으로 사용하는 것이 좋습니다. 우리는 여전히 32 비트와 64 비트 아키텍처 사이의 전환기에 있으며 "부호없는 long long int"는 두 가지 모두에서 같은 의미가 아닙니다.
Rivenhill의 BD

답변:


483

u (부호없는) 변환과 함께 ll (el-el) long long 수정자를 사용하십시오. (Windows, GNU에서 작동).

printf("%llu", 285212672);

11
또는 정확하게 말하자면 GNU libc 용이며 Microsoft의 C 런타임에서는 작동하지 않습니다.
Mark Baker

168
이것은 Linux / UNIX가 아니며 "ll"길이 수정자가 C99의 표준 C에 추가되었습니다. "Microsoft C"에서 작동하지 않으면 표준을 준수하지 않기 때문입니다.
Robert Gamble

12
VS2008에서 나를 위해 일합니다. 또한, 내가 기억하는 한, MS C 컴파일러 (C를 직접 컴파일하도록 설정된 경우)는 설계 상 C90을 준수해야합니다. C99는 모두가 좋아하지 않는 것을 소개했습니다.
스파 파 후미 콘

6
여기서 명심해야 할 것은 여러 long long인수를 전달 printf하고 그 중 하나에 대해 잘못된 형식 을 사용하는 경우 (예 : %d대신) 잘못된 %lld인수 이후 에 인쇄 된 인수 도 완전히 꺼져 있거나 printf충돌을 일으킬 수 있다는 것입니다. ). 기본적으로 변수 인수는 형식 정보없이 printf에 전달되므로 형식 문자열이 올바르지 않으면 결과를 예측할 수 없습니다.
dmitrii

1
허드 허터 스터 터 (Hard Herb Sutter)는 인터뷰에서 마이크로 소프트 고객들이 C99를 요구하지 않기 때문에 순수한 C 컴파일러가 C90에서 동결되었다고 말했다. 이는 C로 컴파일하는 경우에 적용됩니다. 다른 사용자가 위에서 언급 한 것처럼 C ++로 컴파일하는 경우 문제가 없습니다.
ahcox

90

당신은 당신과 같은 유형을 제공하는 inttypes.h 라이브러리를 사용하여 시도 할 수 있습니다 int32_t, int64_t, uint64_t등 당신은 다음과 같은 자사의 매크로를 사용할 수 있습니다 :

uint64_t x;
uint32_t y;

printf("x: %"PRId64", y: %"PRId32"\n", x, y);

이것은 당신에게 같은 문제가주지하는 "보장"되어 long, unsigned long long각 데이터 유형에 얼마나 많은 비트 생각하지 않기 때문에, 등.


여기서이 PRId64, PRId32매크로 정의?
happy_marmoset

4
@happy_marmoset : 그들이에 정의되어 있습니다inttypes.h
나단 Fellman

4
난 당신이 필요하다고 생각 PRIu64하고 PRIu32부호없는 정수에 대한.
Lasse Kliemann

1
inttypes.h표준? 그렇지 stdint.h않습니까?
MD XF

2
정확한 너비의 정수 유형 이없는 아키텍처가 있으므로 이러한 정확한 너비 유형은 선택 사항 입니다. 만 및 유형 (실제로는 표시된보다 넓은 경우도있다) 필수입니다. leastXfastX
DevSolar

78

%d-> int

%u-> unsigned int

%ld-> long int또는long

%lu->에 대한 unsigned long int또는 long unsigned int또는unsigned long

%lld-> long long int또는long long

%llu-> unsigned long long int또는unsigned long long


% lld 또는 % llu에 대해 표시 할 자릿수, 왼쪽 또는 오른쪽 자리 맞춤과 같은 형식 지정자가 있습니까?
Asam Padeh

40

MSVS를 사용하는 long long (또는 __int64)의 경우 % I64d를 사용해야합니다.

__int64 a;
time_t b;
...
fprintf(outFile,"%I64d,%I64d\n",a,b);    //I is capital i

37

Windows에서 % llu가 제대로 작동하지 않고 % d가 64 비트 정수를 처리 할 수 ​​없기 때문입니다. 대신 PRIu64를 사용하는 것이 좋으며 Linux에서도 이식 가능하다는 것을 알 수 있습니다.

대신 이것을 시도하십시오 :

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

int main() {
    unsigned long long int num = 285212672; //FYI: fits in 29 bits
    int normalInt = 5;
    /* NOTE: PRIu64 is a preprocessor macro and thus should go outside the quoted string. */
    printf("My number is %d bytes wide and its value is %" PRIu64 ". A normal number is %d.\n", sizeof(num), num, normalInt);
    return 0;
}

산출

My number is 8 bytes wide and its value is 285212672. A normal number is 5.

내가 본 적이없는 PRIu64에 대한 참조는 +1이지만 PRIu64가 "llu"대신 "lu"로 확장되기 때문에 64 비트 Linux로 이식 할 수없는 것 같습니다.
Rivenhill의 BD

8
그리고 왜 그렇게 나쁠까요? long은 Windows를 제외한 다른 모든 OS에서와 같이 64 비트 Linux에서 64 비트 값입니다.
Ringding

@BDatRivenhill Linux / Unix는 길이가 64 비트 인 LP64를 사용합니다
phuclv

1
그러나 휴대 성을 높이려면 int64_tlong보다 long long이 큰 구현이있을 수 있기 때문에 대신 사용하십시오
phuclv

이것은 정상에 있어야한다! -하나의 작은 업데이트 : 오류 : 리터럴에 유효하지 않은 접미사; C ++ 11은 리터럴과 식별자 사이에 공백이 필요합니다. [-Wreserved-user-defined-literal]
tofutim

14

리눅스에서는 %lluWindows에서는%I64u

Windows 2000에서는 작동하지 않지만 버그가있는 것 같습니다!


Windows의 경우 (또는 최소한 Windows의 경우 Microsoft C 컴파일러의 경우) % I64d, % I32u 및 % I32d도 있습니다
JustJeff

1
Windows 2000과 어떤 관련이 있습니까? C 라이브러리는 printf를 처리하는 라이브러리입니다.
CMircea

1
내가 관찰 한 것. 이 구성을 사용하는 앱을 작성했으며 WinXP에서는 완벽하게 작동했지만 Win2k에서는 쓰레기를 뱉었습니다. 아마도 C 라이브러리가 커널에 만들고있는 시스템 호출과 관련이있을 수도 있고, 알고있는 유니 코드와 관련이있을 수도 있습니다. _i64tot () 또는 이와 유사한 것을 사용하여 문제를 해결해야한다는 것을 기억합니다.
Adam Pierce

7
MS는 "혁신의 자유"를 다시 행사하는 것처럼 들린다. ... ;-)
Dronz

Win2k / Win9x 문제는 unsigned long long데이터 유형이 (현재 C99 표준으로) 비교적 새로운 것이지만 C89 사양 만 지원하는 이전 Microsoft C 런타임을 사용하는 C 컴파일러 (MinGW / GCC 포함) 때문일 수 있습니다. 정말 오래되고 합리적으로 최신 Windows API 문서에만 액세스 할 수 있습니다. 따라서 I64u지원이 언제 빠졌는지 정확하게 말하기는 어렵지만 XP 시대처럼 들립니다.
veganaiZe

8

VS2005를 사용하여 x64로 컴파일하십시오.

% llu는 잘 작동합니다.


3

사람들이 몇 년 전에 쓴 것 외에도 :

  • gcc / mingw에서이 오류가 발생할 수 있습니다.

main.c:30:3: warning: unknown conversion type character 'l' in format [-Wformat=]

printf("%llu\n", k);

그러면 mingw 버전은 기본적으로 c99가 아닙니다. 이 컴파일러 플래그를 추가하십시오 : -std=c99.


3

10 년 넘게 멀티 플랫폼 * 솔루션을 만든 사람은 없었습니다.2008 이후 때문에 필자가 덧붙일 것이다. PLZ 공감. (농담. 상관 없어요)

해결책: lltoa()

사용하는 방법:

#include <stdlib.h> /* lltoa() */
// ...
char dummy[255];
printf("Over 4 bytes: %s\n", lltoa(5555555555, dummy, 10));
printf("Another one: %s\n", lltoa(15555555555, dummy, 10));

OP의 예 :

#include <stdio.h>
#include <stdlib.h> /* lltoa() */

int main() {
    unsigned long long int num = 285212672; // fits in 29 bits
    char dummy[255];
    int normalInt = 5;
    printf("My number is %d bytes wide and its value is %s. "
        "A normal number is %d.\n", 
        sizeof(num), lltoa(num, dummy, 10), normalInt);
    return 0;
}

%lld인쇄 형식 문자열 과 달리이 문자열 은 Windows의 32 비트 GCC에서 작동합니다.

*) 음, 거의 멀티 플랫폼입니다. MSVC에서는 분명히 _ui64toa()대신에 필요 합니다 lltoa().


1
나는 없습니다 lltoa.
Antti Haapala

1

비표준 물건은 항상 이상합니다 :)

GNU에서 긴 부분에 대해서는 L, ll또는q

그리고 창문 아래에서 나는 그것이 ll단지


1

마녀:

printf("64bit: %llp", 0xffffffffffffffff);

산출:

64bit: FFFFFFFFFFFFFFFF

아주 좋아요! 어떻게 16 진수로 표현할 수 있을지 궁금했습니다.
0xAK

그러나 거의 모든 C ++ 및 C 컴파일러는 다음과 같은 경고를 표시합니다. 경고 : 'p'유형 문자와 함께 'll'길이 수정 자 사용 [-Wformat =]
Seshadri R

2
이 완전히 깨진 답변은 이중 정의되지 않은 동작을 가지고 있으며 질문에 대답하기조차 시작하지 않습니다 .
Antti Haapala

@AnttiHaapala이 답변이 이중 정의되지 않은 동작으로 완전히 손상되었다고 말하면 정교하게 말할 수 있습니까 아니면 그냥 삭제해야합니까? 아니면 좋은 나쁜 예를 유지합니까?
lama12345

0

한 가지 방법은 VS2008을 사용하여 x64로 컴파일하는 것입니다.

이것은 예상대로 실행됩니다.

int normalInt = 5; 
unsigned long long int num=285212672;
printf(
    "My number is %d bytes wide and its value is %ul. 
    A normal number is %d \n", 
    sizeof(num), 
    num, 
    normalInt);

32 비트 코드의 경우 올바른 __int64 형식 지정자 % I64u를 사용해야합니다. 그렇게됩니다.

int normalInt = 5; 
unsigned __int64 num=285212672;
printf(
    "My number is %d bytes wide and its value is %I64u. 
    A normal number is %d", 
    sizeof(num),
    num, normalInt);

이 코드는 32 비트와 64 비트 VS 컴파일러 모두에서 작동합니다.


'285212672'대신 실제 64 비트 숫자를 사용해보십시오. 첫 번째 예제가 모든 대상으로 컴파일되어 올바르게 실행된다고 생각하지 않습니다.
dyasta
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.