2010-05-17 12 views
12

Aby odczytać int przy użyciu scanf używamy:użyciu scanf w C/C++

scanf("%d",&i); 

Co jeśli i długo nie int ??

Uwaga: podczas korzystania %d z long daje mi irytujący ostrzeżenie ..

Dzięki!

+4

"Co jeśli" i "długo nie jest int?" - A co, jeśli przeczytasz dokumentację? Standardowa biblioteka jest celowo dobrze udokumentowana (w wielu miejscach). Nigdy nie powinno być potrzeby publikowania pytań, na które można odpowiedzieć przez RTFM. http://www.cplusplus.com/reference/clibrary/cstdio/scanf/ – Clifford

+1

@Clifford: Pokaż mi, gdzie na tej stronie jest napisane, że to błąd, jeśli typ wskaźnika nie pasuje do oczekiwanych? Oczywiście, jeśli właściwie grokuje dostęp do pamięci i jak działa ta funkcja, to oczywiste jest, że "powinien wskazywać na ... obiekty typu określonego przez ich odpowiedni znacznik formatu" jest silne "powinno", ale nie jest to od razu oczywiste, w przeciwnym razie . Z ciekawości wybrałem go "man scanf" ... pierwsze łącze mówi "musi" zamiast "powinien", co jest lepsze, ale gdy opisuję flagę "d", oznacza to, że "następny wskaźnik musi być wskaźnikiem do int "bez wzmianki o możliwych modyfikatorach. –

+0

@Dennis; pomijając fakt, że to pytanie ma ponad rok i mój komentarz nigdy nie podniósł komentarza do tej pory, 'long' nie jest modyfikatorem' int', jest to typ danych sam w sobie - nawet jeśli jest napisane 'long int'. Specyfikator formatu% d ma * "modyfikatory" dla różnych typów liczb całkowitych, a te * są * udokumentowane w podanym przeze mnie łączu. Przez domniemanie, jeśli istnieje specyfikator formatu dla 'long' ("% ld "), specyfikator formatu przeznaczony dla' int' byłby niepoprawny, w przeciwnym razie nie byłoby potrzeby stosowania innego specyfikatora formatu. – Clifford

Odpowiedz

20

Wystarczy użyć

long l; 

scanf("%ld", &l); 

daje mi irytujący ostrzeżenie ..

To ostrzeżenie jest całkiem w porządku. To jest błaganie o uszkodzenie stosu.

+0

Podczas gdy twój kod daje po prostu niezdefiniowane zachowanie. Musisz podać scanf adres zmiennej, która jest czytana. –

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

Można również użyć "%Ld" dla long long (iw zależności od kompilatora, czasami również "%lld").

Zobacz sekcję Konwersje na stronie man scanf, aby uzyskać więcej informacji. (Po prostu Google to, jeśli twój system nie ma stron podręcznika).

+0

A czy ta sama strona man nie mówi, że rzeczy, które czytasz, muszą zostać przekazane do scanf jako wskaźniki? –

+1

Dla 'long long (int)', "% lld" jest standardem (modyfikator "L" jest przeznaczony dla 'long double', więc"% Ld "nie jest standardem, chociaż nie wątpię, że niektóre implementacje pozwalają to). Smaki BSD użyły po raz pierwszy modyfikatora długości "q" dla "quadword", który jest tylko wartością 64-bitową i jestem pewien, że nadal jest akceptowany w niektórych implementacjach opartych na BSD. Microsoft stworzył modyfikatory długości "I64" i "I32", aby określić odpowiednio 64-bitową i 32-bitową liczbę całkowitą, więc "% I64d" byłby w tym przypadku ważny. Innymi słowy, 'long long' to bałagan, jeśli chodzi o sformatowane funkcje I/O. : P – Dustin

6

Na bogów względu:

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

Aby dodać do odpowiedzi Neila, nie można polegać na czymś takim jak "% d", aby przeczytać "długie int", ponieważ określa ono 'int' zamiast' long (int) '. Co więcej, 'int' w niektórych systemach 64-bitowych ma rozmiar 32 bitów, natomiast' long (int) 'ma rozmiar 64 bitów. Innymi słowy, będziesz czytać 32-bitową liczbę całkowitą w tym, co ma być 64-bitowym miejscem przechowywania. Przykładem może być odczyt 2147483649. Ponieważ 32-bitowa wartość jest odczytywana do 64-bitowej lokalizacji, pozostałe 32 bity są pozostawione z dowolnymi wartościami, więc może pojawić się coś takiego jak 6442450945, jeśli wcześniej przechowywano tam 4294967296. – Dustin

3

Każdy specyfikacją konwersji spodziewa się, że odpowiedni argument się z określonym typem; jeśli typ argumentu nie jest zgodny z oczekiwanym typem, zachowanie jest niezdefiniowane. Jeśli chcesz przeczytać w długi z scanf(), trzeba użyć specyfikatora %ld konwersji:

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

sprawdzić w Internecie draft C standard (plik .pdf), sekcja 7.19.6.2, pkt 11 Pełną listę rozmiarów modyfikatory i oczekiwane typy.

-1

Sprawdź to, tutaj jest odpowiedź: "% I64d"

+4

Oprócz bycia niestandardowym rozszerzeniem, 'long' nie jest typem sześćdziesięciu czterech bitów w wielu systemach. –