2010-05-17 19 views
12

Para leer un int usando scanf utilizamos:usando scanf en C/C++

scanf("%d",&i); 

¿Qué pasa si no se i larga int ??

Nota: cuando se utiliza con %dlong me da una advertencia irritante ..

Gracias!

+4

"¿Qué pasa si' i' es largo no int ?? " - ¿Qué pasa si lees la documentación? La biblioteca estándar está intencionalmente bien documentada (en muchos lugares). Nunca debe haber necesidad de publicar preguntas que RTFM pueda responder. http://www.cplusplus.com/reference/clibrary/cstdio/scanf/ – Clifford

+1

@Clifford: Muéstrame en qué parte de la página dice que es un error si el tipo de puntero no coincide con el esperado. Claro, si asimilas correctamente el acceso a la memoria y cómo funciona esta función, es obvio que "debería apuntar a ... objetos del tipo especificado por su etiqueta de formato correspondiente" es un fuerte "debería", pero no es inmediatamente obvio de otra manera . Por curiosidad, busqué en Google "hombre escaneo" ... el primer enlace dice "debe" en lugar de "debería", que es mejor, pero luego cuando se describe la bandera "d", dice "el siguiente puntero debe ser un puntero" to int "sin mencionar los posibles modificadores. –

+0

@Dennis; aparte del hecho de que esta pregunta tiene más de un año y mi comentario nunca mencionó el comentario hasta ahora, 'long' no es un modificador de' int', es un tipo de datos en sí mismo, incluso cuando está escrito 'long int'. El especificador de formato% d * does * have 'modificadores' para diferentes tipos de enteros de tamaño, y esos * están * documentados en el enlace que di. Por implicación, si hay un especificador de formato específico para 'long' ("% ld "), entonces el especificador de formato destinado a' int' sería incorrecto, de lo contrario no habría necesidad de especificar el formato diferente. – Clifford

Respuesta

20

sólo tiene que utilizar

long l; 

scanf("%ld", &l); 

me da una advertencia irritante ..

Esa advertencia es del todo bien. Esto está pidiendo corrupción de pila.

+0

Considerando que su código simplemente da un comportamiento indefinido. Debe darle a scanf la dirección de la variable que se lee. –

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

También se puede utilizar para una "%Ld"long long (y dependiendo de su compilador, a veces también "%lld").

Eche un vistazo a la sección Conversiones de la página del manual de escaneo para obtener más información. (Solo busque en Google si su sistema no tiene páginas de manual).

+0

¿Y esa misma página de manual no dice que las cosas que está leyendo deben pasarse a scanf como punteros? –

+1

Para 'long long (int)', "% lld" es estándar (el modificador "L" está destinado a 'long double', por lo que"% Ld "no es estándar, aunque no dudo de que algunas implementaciones lo permitan eso). Los sabores de BSD utilizaron una vez el modificador de longitud "q" para una "quadword", que es solo un valor de 64 bits, y estoy razonablemente seguro de que todavía se acepta en algunas implementaciones basadas en BSD. Microsoft creó los modificadores de longitud "I64" e "I32" para especificar un entero de 64 bits y de 32 bits, respectivamente, por lo que "% I64d" sería válido en ese caso. En otras palabras, 'long long' es un caos de confusión cuando se trata de las funciones de E/S formateadas. : P – Dustin

6

Para dioses sake:

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

Para agregar a la respuesta de Neil, no puede confiar en algo como "% d" para leer un 'long int' porque eso especifica un' int' en vez de 'long (int)'. No solo eso, 'int' en algunos sistemas de 64 bits tiene un tamaño de 32 bits, mientras que' long (int) 'tiene un tamaño de 64 bits. En otras palabras, estaría leyendo un entero de 32 bits en lo que se supone que es una ubicación de almacenamiento de 64 bits. Un ejemplo sería leer 2147483649. Dado que el valor de 32 bits se lee en una ubicación de 64 bits, los otros 32 bits se quedan con los valores que estaban presentes, por lo que podría obtener algo como 6442450945 si tuviera 4294967296 almacenado allí originalmente. – Dustin

3

Cada especificador de conversión espera que su correspondiente argumento sea de un tipo específico; si el tipo del argumento no coincide con el tipo esperado, entonces el comportamiento no está definido. Si desea leer en un largo con scanf(), es necesario utilizar el especificador de conversión %ld:

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

Comprobar la línea draft C standard (archivo .pdf), la sección 7.19.6.2, el párrafo 11 para obtener una lista completa de tamaño modificadores y tipos esperados.

-1

Compruebe esto, aquí está la respuesta: "% I64d"

+4

Además de ser una extensión no estándar, 'long' no es un tipo de sesenta y cuatro bits en muchos sistemas. –