2012-12-28 5 views
10

Ich habe dieses Stück Code, das mein Wissens all C. ist eine Herausforderung Hier hat ich:Was stimmt nicht mit printf ("% llx")?

int main(void){ 
    unsigned long long int massage ; 

    scanf("%llX", &massage); //input: 0x1234567890abcdef 
    printf("%llX", massage); 
    return 0; 
} 

Auf meinem „64bit - Corei5 - Fedora - GCC“ druckt es genau, was ich es zugeführt. aber auf meinem Buddy-System (32bit, MS XP, MinGW) druckt es 90ABCDEF. Ich verstehe nicht warum. weiß jemand?

BTW: sizeof(unsigned long long int) auf seinem System ist 8.

+3

Er benutzt MSVC oder so? Sie haben nicht standardmäßige 'printf'- und' scanf'-Formate. Sollte in der Dokumentation des Compilers zu finden sein. –

+0

er verwendet MINGW. (bearbeitet die Frage) – Untitled

+2

Verwendet MinGW eine eigene C-Bibliothek, oder benutzt sie die Windows-Bibliothek? Im letzteren Fall gelten die Nicht-Standardformate weiterhin. In ersterem keine Ahnung. –

Antwort

9

Das Problem ist, eine Diskrepanz zwischen dem, was der Compiler glaubt (wie in sizeof wider: sizeof(unsigned long long int) zur Compile-Zeit ausgewertet wird) und was die Laufzeitbibliothek glaubt (wie in printf wider: die printf Funktion wird zur Laufzeit aufgerufen, das ist, wenn seine Format-Bezeichner wirksam werden).

Nach "C99" in the MinGW documentation:

GCC enthält keine C-Laufzeitbibliothek. Dies wird von der Plattform bereitgestellt. Der MinGW-Port von GCC verwendet Microsofts ursprüngliche (alte) Visual C-Laufzeitversion MSVCRT, auf die Microsoft Visual Studio 6 (veröffentlicht 1998) abzielte.

[& hellip;]

Da MinGW auf MSVCRT beruht, es viele der gleichen Einschränkungen und Marotten mit Kompatibilität als Visual Studio hat 6. Sie sollten davon ausgehen, dass MinGW Anwendungen, die nicht auf C99 Verhalten verlassen können, nur auf C89. Beispielsweise werden die neueren Formatzeichen in printf wie% a und% ll nicht unterstützt, obwohl ein workaround for %ll vorhanden ist.

(Die Problemumgehung, die es erwähnt ist I64 statt ll zu verwenden. So, %I64X ärgerlicher, zumindest auf meinem System wird GCC eine Warnung ausgeben, wenn es in einem wörtlichen Format-String, der sieht, weil es nimmt an, dass es eine bessere Laufzeitbibliothek haben wird.)

+0

Sie könnten Präprozessor-String-Verkettung verwenden, um die GCC-Warnung zu umgehen. Es wird Ihren Code nicht schöner machen, aber zumindest wird er den richtigen Code für die richtige Bibliothek verwenden. –

+0

@Tinctorius: Es ist nicht so, dass es schwierig ist, die Warnung zu umgehen - man kann zum Beispiel den Format-String einfach in einer temporären Variablen speichern - es ist einfach nervig zu müssen. :-P – ruakh

+1

Es ist immer noch schön, dass Ihr Compiler Ihre Formatzeichenfolge überprüft. Schließlich hängt die Korrektheit der Formatzeichenfolge von den anderen Argumenten für "printf" und "scanf" ab, also ist es in gewisser Weise Teil der Funktion. Sie könnten stattdessen die Präprozessor-Konstante 'HEX64' erstellen, die zu"% I64X "für MSVCRT-Builds und"% llX "für POSIX-ähnliche Builds führt. Dann können Sie 'printf schreiben (" Ich mag die Nummer "HEX64"! ", Nummer)', und GCC kann immer noch prüfen, ob der Typ der 'Nummer' mit der Formatzeichenfolge übereinstimmt. –

Verwandte Themen