2010-05-17 5 views
12

einen int mit scanf wir verwenden Zum Lesen
mit scanf in C/C++

Hinweis: Wenn %d mit long mit es mir eine irritierende Warnung gibt ..

Dank!

+4

"Was ist wenn' i' ist lang nicht int ?? " - Was ist, wenn Sie die Dokumentation lesen? Die Standardbibliothek ist absichtlich gut dokumentiert (an vielen Stellen). Es sollte niemals notwendig sein, Fragen zu stellen, die von RTFM beantwortet werden könnten. http://www.cplusplus.com/reference/clibrary/cstdio/scanf/ – Clifford

+1

@Clifford: Zeigen Sie mir, wo auf dieser Seite es heißt, es ist ein Fehler, wenn der Zeigertyp nicht entspricht, was erwartet wird? Sicher, wenn Sie richtig Speicherzugriff und wie diese Funktion funktioniert, ist es offensichtlich, dass "sollte zeigen auf ... Objekte des Typs durch ihre entsprechende Format-Tag angegeben" ist eine starke "sollten", aber es ist nicht sofort offensichtlich, sonst . Aus Neugierde habe ich gegoogelt "man scanf" ... der erste Link sagt "Muss" statt "sollte", was besser ist, aber dann, wenn die "d" -Flagge geschrieben wird, heißt es "der nächste Zeiger muss ein Zeiger sein zu int "ohne die möglichen Modifikatoren zu erwähnen. –

+0

@Dennis; Abgesehen von der Tatsache, dass diese Frage älter als ein Jahr ist und mein Kommentar nie einen Kommentar ausgelöst hat, ist "long" kein Modifikator von "int", sondern ein eigener Datentyp - auch wenn "long int" geschrieben wurde. Der% d-Formatbezeichner * hat * Modifizierer für ganzzahlige Integer-Typen, und diese * sind * in dem von mir angegebenen Link dokumentiert. Implizit, wenn es einen spezifischen Formatbezeichner für "long" ("% ld") gibt, wäre der Formatspezifizierer, der für "int" bestimmt ist, inkorrekt, da sonst kein anderer Formatbezeichner benötigt würde. – Clifford

Antwort

20

Verwenden Sie einfach

long l; 

scanf("%ld", &l); 

es gibt mir eine irritierende Warnung ..

Diese Warnung ganz richtig ist. Dies ist um Stapel Korruption betteln.

+0

Während Ihr Code einfach undefiniert Verhalten gibt. Sie müssen scanf die Adresse der Variablen eingeben, in die eingelesen wird. –

2
scanf("%ld", &i); 

Sie auch "%Ld" für eine long long verwenden können (und je nach Compiler, manchmal auch "%lld").

Weitere Informationen finden Sie im Abschnitt "Conversions" der scanf man-Seite. (Rufen Sie Google einfach auf, wenn Ihr System keine Hilfeseiten hat).

+0

Und sagt nicht die gleiche Manpage, dass die Dinge, die Sie gerade lesen, als Zeiger an scanf weitergegeben werden müssen? –

+1

Für 'long long (int)' ist "% lld" Standard (der "L" -Modifikator ist für 'long double' gedacht, also ist"% Ld "kein Standard, obwohl ich nicht bezweifle, dass es einige Implementierungen erlauben es). BSD-Flavours verwendeten einmal den "q" -Längenmodifikator für ein "Quadwort", was nur ein 64-Bit-Wert ist, und ich bin ziemlich sicher, dass es immer noch in einigen BSD-basierten Implementierungen akzeptiert wird. Microsoft hat die Längenmodifikatoren "I64" und "I32" erstellt, um eine 64-Bit- bzw. eine 32-Bit-Ganzzahl anzugeben. In diesem Fall wäre also "% I64d" gültig. Mit anderen Worten, 'long long' ist ein Chaos der Verwirrung, wenn es um die formatierten I/O-Funktionen geht. : P – Dustin

6

Für Götter willen

long n; 
scanf("%ld", & n); 
+1

Um Neils Antwort hinzuzufügen, können Sie sich nicht auf etwas wie "% d" verlassen, um einen 'long int' zu lesen, weil das ein' int' anstatt ein 'long (int)' angibt. Nicht nur, dass "int" auf einigen 64-Bit-Systemen 32 Bits groß ist, während "long (int)" 64 Bits groß ist. Mit anderen Worten, Sie würden eine 32-Bit-Ganzzahl in einem 64-Bit-Speicherort lesen. Ein Beispiel wäre das Lesen von 2147483649. Da der 32-Bit-Wert in eine 64-Bit-Position gelesen wird, bleiben die anderen 32 Bits mit den Werten, die vorhanden waren, also könnten Sie etwas wie 6442450945 erhalten, wenn Sie ursprünglich 4294967296 dort gespeichert hatten. – Dustin

3

Jeder Konvertierungsspezifizierer erwartet sein entsprechendes Argument eines bestimmten Typs zu sein; Wenn der Typ des Arguments nicht mit dem erwarteten Typ übereinstimmt, ist das Verhalten nicht definiert. Wenn Sie mit scanf() in eine lange lesen möchten, müssen Sie den %ld Konvertierungsspezifizierer verwenden:

long i; 
scanf("%ld", &i); 

Überprüfen Sie die Online-draft C standard (PDF-Datei), Abschnitt 7.19.6.2, Ziffer 11 für eine vollständige Auflistung der Größe Modifikatoren und erwartete Typen.

-1

Überprüfen Sie dies, hier ist die Antwort: "% I64d"

+4

Zusätzlich zu einer nicht standardmäßigen Erweiterung ist 'long' auf vielen Systemen kein 64-Bit-Typ. –