[XP64] fscanf() liest size_t falsch ein

Onkel Schuppig

Erfahrenes Mitglied
Hallo Leute,
beim Erstellen einer 64-Bit-Anwendung habe ich bei fscanf() ein Problem:
C++:
FILE* file = fopen("daten.txt", "r");
// ...
size_t anzahl;
fscanf (file, "%d", &anzahl);
Bei 32 Bit funktioniert das einwandfrei, bei 64 bekomme ich eine völlig falsche Zahl zurück.
Was kann man machen, damit es unter 32 wie unter 64 Bit sauber läuft?
Ich benutze Visual C++ 2008 Prof.
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

der Formatspezifizierer %d erwartet als Argument ein int *. size_t ist aber 1. ein vorzeichenloser Typ und 2. im 32-Bit-Modus von VS2008 ein unsigned int, im 64-Bit-Modus allerdings ein unsigned __int64. Probier es also mal so:
C:
unsigned int anzahl;
fscanf (file, "%u", &anzahl);

Grüße,
Matthias
 
Hi.

Btw, moderne C-Compiler kennen den z Modifizierer bei *scanf. MS hat den C99 Standard immer noch nicht implementiert - und wir haben schon 2010... :rolleyes:

Am besten verwendet man den C++ Compiler von MS als "besseres C" wenn man C Code in MS kompilieren will...

Gruß
 
Auf meiner 64-Bit-Kiste ist nun
sizeof(size_t) == 8,
sizeof(unsigned int) == 4,
sizeof(unsigned long int) == 4,

Über letzters bin ich erstmal geschockt. Wie kann ich denn 64 Bit nutzen, wenn die Basistypen das gar nicht hergeben? Ein size_t lässt sich auch mit "%u" nicht einlesen.
 
Hi.
Auf meiner 64-Bit-Kiste ist nun
sizeof(size_t) == 8,
sizeof(unsigned int) == 4,
sizeof(unsigned long int) == 4,

Über letzters bin ich erstmal geschockt.
Das ist normal. Der Standard verlangt nur das sizeof(long) >= sizeof(int) ist.
Wie kann ich denn 64 Bit nutzen, wenn die Basistypen das gar nicht hergeben?
Kennt dein Compiler "long long int"?

(Ich frag lieber nicht ob dein Compiler / C Bibliothek den C99 Header stdint.h kennt, wo Typen mit spezifizierter Größe definiert werden a lá uint32_t etc.)
Ein size_t lässt sich auch mit "%u" nicht einlesen.
Dann mußt du auf die Erweiterung von MS zurückgreifen:
C:
scanf("%I64u", &a_size_t); // funktioniert nur wenn size_t auch wirklich ein unsigned __int64 ist!
Matthias hatte allerdings auch nicht vorgeschlagen einen size_t zu verwenden, sondern einen unsigned int... (den eingelesenen Wert kannst du ja danach immer noch einem size_t zuweisen)

Wenn du die entsprechenden Dateien auf 32 und 64 bit Plattformen verwenden willst, ist es sowieso keine gute Idee einen plattformabhängigen Typ zu verwenden.

Gruß
 
Ja, long long kennt der Compiler.
Wenn ich also nun einen 64-Bit-Integer einlesen (oder speichern) will, sollte ich "%I64" als Formatspezifizierer wählen. Schöner wäre natürlich was Portables.
Alternativ könnte ich ja die iostream-lib benutzen. Die fällt leider durch, ist sie doch 10-mal langsamer als die stdio-lib. Das ist bei großen Dateien inakzeptabel. :-(
Danke.
 

Neue Beiträge

Zurück