2011-04-12 53 views
5

Me pregunto cómo funciona la función de biblioteca C estándar scanf() si la entrada es un número entero o un carácter cuando llamamos scanf ("% d", & var) cuando un caracter en sí mismo es solo un número? Sé que cuando encuentra un no entero lo pone de nuevo en el búfer de entrada y devuelve un -1, pero ¿cómo sabe que la entrada no es un número entero?¿cómo chequea() si la entrada es un número entero o un carácter?

Respuesta

3

Tiene razón en que cada personaje se representa realmente como un entero de 8 bits. La solución es simple: observe ese número y vea si está en el rango 48-57, que es el rango de códigos SCII para los caracteres '0' - '9'.

A partir de la línea 1315 del scanf()source code podemos ver esto en acción. scanf() es realmente más complicado, aunque también busca caracteres de varios bytes para determinar el valor numérico. La línea 1740 es donde ocurre la magia y ese personaje se convierte en un número. Finalmente, y posiblemente esta sea la más útil, la función strtol() realiza el bucle para realizar esa conversión.

+0

¡Gracias por la explicación y referencia al código fuente! – vjain27

3

La entrada es siempre una cadena. Si scanf espera un número entero (porque lo pasó "%d"), intenta convertir la cadena en un número entero para usted.

+0

Pero lo que de entrada sería una secuencia de valores ASCII que son todos los números. ¿No es así? – vjain27

+0

valores ASCII que representan números, quieres decir. scanf toma el carácter '9', decide que representa un número y lo convierte a un número entero 9. – Marvo

+0

Sí, eso es lo que debería hacer. El teclado enviará caracteres ascii solamente. – vjain27

0

Trata de analizar un entero decimal válido desde el comienzo de la secuencia, en la práctica opcional + o - y luego la secuencia de uno o más dígitos.

+0

¿Podría explicar cómo lo analiza? Por ej. ¿cómo se diferenciará entre una A y el valor 65 porque A pasará como 65 - su valor ascii? – vjain27

+0

Uh scant intenta leer la representación ASCII de un entero decimal aquí. La letra A no es parte de tal. –

0

Básicamente utiliza un bucle como:

while (isdigit((ch=getchar())) 
    // ... 
+0

Lo tengo. ¡Gracias! – vjain27

0

usted no entiende el especificador de formato %d. Hace no devuelve el valor ASCII del carácter ingresado (puede usar %c para eso); devuelve el número entero que representan los caracteres. Por lo tanto, en un carácter de entrada de '9', %d devuelve el valor 9 - no el valor ASCII de '9'.

(Bueno, en realidad %d mira a una secuencia de caracteres, por lo que si la entrada es '9' seguido por '0' seguido por ' ', que va a interpretarlo como 90).

1

Básicamente, la función scanf coincide con expresiones regulares basadas en el especificador de conversión que pasa. Si especifica %d, que cuenta scanf para que coincida con la entrada con una expresión regular que es uno o más caracteres entre '0' y '9' (opcionalmente con un + o - personaje principal). Luego convierte esa secuencia de caracteres al valor entero equivalente.

Un muy versión simplista podría ser algo como esto:

while (isdigit(c = fgetc(stream)) 
    val = val * 10 + valueOf(c); 
ungetc(c, stream); 

donde isdigit es una función de la biblioteca estándar que devuelve verdadero (distinto de cero) si el valor de carácter representa un dígito decimal, y valueOf es una función definida por el usuario que asigna el carácter que representa un número entero ('0' - '9') al valor entero equivalente (0 - 9) (No conozco una función de biblioteca estándar que haga eso para valores de caracteres individuales).¿Por qué no simplemente restar '0' de c para obtener el valor entero equivalente? Dependiendo de la codificación, no se garantiza que todos los caracteres enteros decimales se distribuirán en orden (All The World Is Not ASCII); es mejor delegar la conversión real en una función que tenga en cuenta la codificación actual.

2

En la declaración scanf usted está mencionando% d que es la celebración número entero solamente lo que por defecto se entenderá que la variable como número entero

Cuestiones relacionadas