2011-06-12 15 views
11

Por man me parece

   printf("%*d", width, num); 

y

   printf("%2$*1$d", width, num); 

son equivalentes.

Pero la OMI el segundo estilo debe ser el mismo que:

   printf("%*d", num, width); 

Sin embargo a través de las pruebas parece man es correcto; ¿por qué?

+4

¿Estás preguntando "por qué' hombre "está bien?" Después de todo, es _la_ documentación. – Vlad

+1

'2 $ *' debe coincidir con el segundo parámetro, mientras que '1 $ d' debe coincidir con el primero, pero resulta que no es cierto en el caso de' printf ("% 2 $ * 1 $ d", ancho, num); ' –

Respuesta

21

La parte pertinente de la especificación POSIX de printf() define este comportamiento:

Las conversiones pueden ser aplicadas a la n ésimo argumento después de que el formato deen la lista de argumentos, en lugar de a la siguiente sin utilizar argumento. En este caso, el carácter especificador de conversión% (ver abajo) se reemplaza por la secuencia "% n $", donde n es un entero decimal en el rango [1, {NL_ARGMAX}], dando la posición del argumento en la lista de argumentos Esta característica proporciona la definición de cadenas de formato que seleccionan argumentos en un orden apropiado para idiomas específicos (ver la sección EJEMPLOS).

El formato puede contener especificaciones de conversión argumento numeradas (es decir, "% n $" y "* m $"), o especificaciones de conversión argumento sin numerar (es decir,% y *), pero no ambos. La única excepción a esto es que %% se puede mezclar con el formulario "% n $". Los resultados de mezclar especificaciones de argumento numeradas y no numeradas en una cadena de formato no están definidas. Cuando se utilizan especificaciones de argumento numeradas, especificar el argumento N th requiere que todos los argumentos iniciales, desde el primero hasta el (N-1) th, se especifiquen en la cadena de formato.

En las cadenas de formato que contienen la especificación de conversión "% n $", los argumentos numerados en la lista de argumentos se pueden referenciar desde la cadena de formato las veces que sea necesario.

El %n$ identifica el argumento cuyo valor se va a imprimir - argumento 2 en su ejemplo.

El *n$ identifica el argumento cuyo valor debe tratarse como el ancho del formato - argumento 1 en su ejemplo.

Por lo tanto, los que escriben el manual siguen el estándar.


Usted sostiene en un comentario:

2$* debe coincidir con el segundo parámetro, mientras que 1$d debe coincidir con el primero, pero resulta que no es cierto en el caso de printf("%2$*1$d", width, num);.

Como se ha señalado ya, la norma atribuye claramente los n$ partes como modificadores de sufijo de % y *, en lugar de modificadores como prefijo del especificador de conversión de formato (d en este ejemplo) y *. Su diseño putativo podría, probablemente, ponerse a trabajar, pero no fue el diseño elegido.

+0

Buen lugar, lo estaba interpretando como' n $ * 'y'% n $ '. –

+0

+1 mucho más claro que mi respuesta. –

+0

+1 ¡Dios mío, no sabía de esto! – phoxis

3

En su segundo ejemplo:

printf("%2$*1$d", width, num); 

El primer número, 2, está unido al especificador de formato, y el segundo número, 1, está unido a la *. Si lee la documentación para printf, esto es claro. Nada inusual está sucediendo.

1

una anchura de campo o de precisión, o ambos, puede ser indicado por un asterisco '*' o un asterisco seguido de uno o más dígitos decimales y una `$' en lugar de una cadena de dígitos.

Por lo tanto, el 1$ se aplica al asterisco, por lo tanto, el primer argumento es el ancho. El 2$ se aplica a la especificación de formato completa, por lo tanto, el segundo argumento es aquel cuyo valor se imprimirá.

Cuestiones relacionadas