Pregunta

¿Cuáles son las diferencias entre usar scanf con los siguientes especificadores de formato, cuando la entrada que se escanea es 123456 versus cuando es 123:

  • %6d
  • %-6d
  • %0d

¿Cuáles son las diferencias en la salida?

¿Fue útil?

Solución

Terminé solo probándolo con GCC 4.3.4 y obtuve lo siguiente:

  • %6d: Funciona bien; Solo lee 6 caracteres (así que si intentas leer 123456789 solo se leerá 123456)
  • %-6d: Emite la advertencia:

    warning: unknown conversion type character '-' in format
    

    No lee nada, y el int se escribe no está modificado

  • %0d: Emite la advertencia:

    warning: zero width in scanf format
    

    Lee como si no hubiera ancho en el especificador de formato (%d)

No he verificado la especificación para ver si esos resultados son obligatorios o cómo lo maneja GCC (EDITAR: Andreyt lo encontró)

Otros consejos

los %-6d es un especificador de formato no válido. No hay especificadores de formato con - en ellos en scanf.

En %6d la 6 Se llama parte Ancho de campo máximo. Funciona con todos los especificadores de formato (no solo con d) y especifica el número máximo de caracteres para leer antes de que se realice cualquier conversión específica del formato. Por ejemplo, si la secuencia de entrada es 1234567, después %3d leerá y convertirá 123 y %6d leerá y convertirá 123456.

los %0d es un especificador de formato no válido. Ancho de campo máximo en scanf Debe ser un entero no cero (ver 7.19.6.2/3 en la especificación del idioma).

Entonces, eso nos deja con %6d Como el único especificador de formato significativo entre los tres que proporcionó. En estas circunstancias, la pregunta sobre las diferencias en la producción (¿en los resultados?) Tiene poco sentido.

EDITAR: Probablemente se pueda argumentar que en %-6d la -6 Parte es el ancho de campo máximo, que satisface el requisito estándar de ser entero decimal no cero. Sin embargo, en la terminología del lenguaje C A entero decimal Como elemento léxico es una secuencia de dígitos y dígitos solamente. No se le permite incluir un letrero. Es decir, tampoco -6 ni +6 son enteros decimales. Cada vez que usas -6 o +6 Como enteros en su programa, en realidad es unary - y + Operador Lexeme seguido de decimal Integer Lexeme. Entonces, desde la especificación de scanf requiere un entero decimal no cero Como ancho de campo máximo, debe ser un entero sin letreros.

Esto es lo que creo que sucederá: %6d le dará los primeros 6 dígitos del número, %-6d probablemente no funcionará como espere, ya que es más un especificador de alineación de salida. %0d significaría que solo quieres 0 caracteres, lo que probablemente no funcionaría como se esperaba.

Ambas cosas %-6d y %0d son inválido Especificaciones de conversión para scanf, entonces el comportamiento para esos casos será indefinido. Ver el idioma estándar, § 7.19.6.2, ¶ 3.

Asumiré, como Arkadiy, que realmente te referiste al formato de estilo Printf, ya que te refieres a "salida". También asumiré que estás usando C (como sugiere la etiqueta).

Si tu corres:

printf("%6d %-6d %0d", num1, num2);

... Terminará con errores del compilador (o, peor aún, errores de tiempo de ejecución), ya que no ha proporcionado suficientes argumentos para tres formatos.

Sin embargo, tengo la sensación de que eso no es lo que estabas preguntando. Supongamos que realmente ejecutas:

// (I've added some extra stuff to show how the formatting works.)
printf("'%6d'/'%-6d'/'%0d'", num2, num2, num2);

...obtendrás:

'   123'/'123   '/'123'

Normalmente, si el ancho de campo (6 en este caso) es lo suficientemente ancho, los números están alineados a la derecha, con trastornos espaciales. Si pone un '-' antes del ancho del campo, estarán alineados con el derecho, con trastornos del espacio.

La sutileza aquí está en el formato "%0D". Podrías pensar que estás especificando un campo de ancho cero ... y te equivocarías. Lo primero después del '%' es un indicador de opción, y '0' es una bandera válida. Significa: "Si el ancho de campo es más ancho que el contenido, la cabeza izquierda con ceros". En este caso, no ha suministrado un ancho de campo (el '0' es una bandera, ¿recuerdas?), Por lo que el indicador '0' no tiene ningún efecto: el campo será tan amplio como lo requiera el contenido.

Sin embargo, hay una sutileza aún peor. Si especificó "%-06d", obtendrá un salto derecho con ceros, ¿verdad? Mmm no. La bandera '-' anula el indicador '0', cualquiera que sea el orden que se suministren. Obtendrías '123'.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top