2008-08-05 21 views
281
#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; 
} 

Ausgang:Wie printf ein unsigned long long int (der Formatbezeichner für unsigned long long int)?

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

Ich nehme an, das unerwartete Ergebnis aus ist die unsigned long long int Druck. Wie geht es dir printf() ein unsigned long long int?

+1

Siehe auch http://StackOverflow.com/questions/5140871/sprintf-for-ununsigned-int64 – hippietrail

+0

Ich würde vorschlagen, mit stdint.h und explizite über die Anzahl der Bits in Ihrer Variablen. Wir befinden uns immer noch in einer Übergangszeit zwischen 32- und 64-Bit-Architekturen, und "unsigned long long int" bedeutet für beide nicht dasselbe. –

+1

Ich habe gerade Ihren Code (mit% llu) mit gcc kompiliert und die Ausgabe war die richtige. Übergeben Sie irgendwelche Optionen an den Compiler? – Juan

Antwort

371

Verwenden Sie den Modifikator ll (el-el) long-long mit der Konvertierung u (unsigned). (Arbeitet in Windows, GNU).

printf("%llu", 285212672); 
+14

Funktioniert nicht auf Windows - das ist Nur für Linux/UNIX. –

+6

Oder um genau zu sein ist es für GNU libc und funktioniert nicht mit Microsoft C-Laufzeit. –

+133

Dies ist keine Linux/UNIX-Sache, der "ll" -Längenmodifikator wurde zu Standard C in C99 hinzugefügt, wenn es in "Microsoft C" nicht funktioniert, dann ist es, weil sie nicht standardkonform sind. –

4

Nicht-Standard-Dinge sind immer seltsam :)

für den langen langen Abschnitt unter GNU ist es L, ll oder q

und unter Windows Ich glaube, es ll ist nur

1

Nun, eine Möglichkeit besteht darin, es als x64 mit VS2008

zu kompilieren

10 Das läuft wie Sie es erwarten würden:

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); 

Für 32-Bit-Code, müssen wir die richtige __int64 Formatbezeichner% I64u benutzen. So wird es.

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); 

Dieser Code funktioniert für 32 und 64-Bit-VS-Compiler.

71

Möglicherweise möchten Sie versuchen, die inttypes.h Bibliothek, die Sie Typen wie int32_t gibt, int64_t, uint64_t usw. Sie können dann ihre Makros verwenden wie:

uint64_t x; 
uint32_t y; 

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

Dieses „garantiert "Ihnen nicht die gleichen Probleme wie long, unsigned long long usw. zu geben, da Sie nicht erraten müssen, wie viele Bits in jedem Datentyp enthalten sind.

+0

wo diese 'PRId64',' PRId32' Makros definiert sind? –

+3

@happy_marmoset: sie sind definiert in 'inttypes.h' –

+2

Ich denke, Sie brauchen' PRIu64' und 'PRIu32' für unsigned Ganzzahlen. –

29

Das liegt daran,% llu funktioniert nicht ordnungsgemäß unter Windows und% d kann nicht 64-Bit-Ganzzahlen verarbeiten. Ich schlage vor, stattdessen PRIu64 zu verwenden, und Sie werden feststellen, dass es auch für Linux portabel ist.

Versuchen Sie stattdessen:

#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; 
} 

Ausgabe

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

+1 für den Verweis auf PRIu64 gefunden werden können, die ich nie gesehen hatte, aber das scheint nicht portable zu 64-Bit-Linux (zumindest) weil PRIu64 erweitert sich zu "lu" statt "llu". –

+6

Und warum wäre das schlecht? Ein Long ist ein 64-Bit-Wert auf 64-Bit-Linux, wie auf jedem anderen Betriebssystem außer Windows. – Ringding

+0

@BDatRivenhill Linux/Unix verwendet LP64, in dem long ist 64 Bits –

8

In Linux es %llu ist und in Windows ist es %I64u

Obwohl ich gefunden habe, es nicht in Windows 2000 funktioniert , da scheint ein Fehler zu sein!

+0

mit Fenstern geben kann (oder zumindest Mit dem Microsoft C-Compiler für Windows gibt es auch% I64d,% I32u und% I32d – JustJeff

+1

Was hat es mit Windows 2000 zu tun? Die C-Bibliothek behandelt printf. – CMircea

+1

Genau was ich beobachtet habe. Ich schrieb eine App, die dieses Konstrukt verwendete und es funktionierte perfekt auf WinXP, spuckte aber Müll auf Win2k. Vielleicht hat es etwas mit einem Systemaufruf zu tun, den die C-Bibliothek an den Kernel stellt, vielleicht hat es etwas mit Unicode zu tun, wer weiß. Ich erinnere mich, dass ich mit _i64tot() oder so etwas umgehen musste. –

33

Für lange lange (oder __int64) mit MSVS, sollten Sie% I64d verwenden:

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

Das funktioniert auch:% I64x –

8

Kompilieren es als x64 mit VS2005:

% llu gut funktioniert.

26

%d -> für int

%ld -> für long int

%lld -> für long long int

%llu -> für unsigned long long int

4

Hex:

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

Ausgang:

64bit: FFFFFFFFFFFFFFFF 
+0

Sehr schön! Ich fragte mich, wie ich es in Hex-Darstellung bekommen konnte –

+0

Aber fast alle C++ und C-Compiler geben die Warnung: ** Warnung: Verwendung von 'll' Länge Modifikator mit 'p' Zeichen [-Wformat =] ** –

2

Zusätzlich zu dem, was die Menschen vor Jahren schrieb:

  • Sie diesen Fehler könnte auf gcc/mingw:

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

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

Dann ist Ihre Version von Mingw nicht standardmäßig auf c99. Fügen Sie dieses Compiler-Flag hinzu: -std=c99.

Verwandte Themen