¿Cómo formatear cadenas usando printf () para obtener la misma longitud en la salida?

92

Tengo dos funciones, una que produce mensajes como Starting initialization...y otra que verifica códigos de retorno y salidas "Ok", "Warning"o "Error". Sin embargo, la salida que se produce es de diferente longitud:

Starting initialization...Ok.
Checking init scripts...Ok.

¿Cómo puedo conseguir algo como esto?

Starting initialization...       Ok.
Checking init scripts...         Ok.
psihodelia
fuente

Respuestas:

159

Puede especificar el ancho en los campos de cadena, p. Ej.

printf("%-20s", "initialization...");

y luego todo lo que se imprima con ese campo se rellenará en blanco con el ancho que indique.

La -izquierda justifica su texto en ese campo.

Carl Smotricz
fuente
130
Por desgracia, no soy lo suficientemente inteligente para contar tan alto. Sin embargo, confío en que el autor de la pregunta sea lo suficientemente inteligente como para extrapolar mi ejemplo :)
Carl Smotricz
3
¿Qué pasa con la justificación correcta? No hay banderas mencionadas en K&R
Ungeheuer
9
Justificado a la derecha es el valor predeterminado. Sin un -, sus datos estarán justificados a la derecha en un campo cuyo ancho haya especificado.
Carl Smotricz
24

printfpermite formatear con especificadores de ancho. p.ej


printf( "%-30s %s\n", "Starting initialization...", "Ok." );

Usaría un especificador de ancho negativo para indicar la justificación a la izquierda porque el valor predeterminado es usar la justificación a la derecha.

PÁGINAS.
fuente
18

Además, si desea la flexibilidad de elegir width, puede elegir entre uno de los dos formatos siguientes (con o sin truncamiento):

int width = 30;
//no truncation uses %-*s
printf( "%-*s %s\n", width, "Starting initialization...", "Ok." );
// output is "Starting initialization...     Ok."

//truncated to the specified width uses %-.*s
printf( "%-.*s %s\n", width, "Starting initialization...", "Ok." ); 
// output is "Starting initialization... Ok."
Balance de vida
fuente
13

También está el %nmodificador que puede ayudar en determinadas circunstancias. Devuelve la columna en la que estaba la cadena hasta ahora. Ejemplo: desea escribir varias filas que estén dentro del ancho de la primera fila como una tabla.

int width1, width2;
int values[6][2];
printf("|%s%n|%s%n|\n", header1, &width1, header2, &width2);

for(i=0; i<6; i++)
   printf("|%*d|%*d|\n", width1, values[i][0], width2, values[i][1]);

imprimirá 2 columnas del mismo ancho de cualquier longitud que las dos cadenas header1y header2puede tener. No sé si todas las implementaciones tienen el %npero Solaris y Linux sí.

Patrick Schlüter
fuente
Esta solución funciona, pero cualquiera que tome esto y lo ponga en su código debe ser consciente del riesgo de introducir vulnerabilidades en la memoria .
Matthew Cole
0

También existe la solución de baja tecnología de contar y agregar espacios a mano para alinear sus mensajes. Nada le impide incluir algunos espacios finales en las cadenas de sus mensajes.

Carl Smotricz
fuente
-2

Comience con el uso de Tabs, el modificador de carácter \ t . Avanzará a una ubicación fija (columnas, jerga de la terminal). Sin embargo, no ayuda si hay diferencias de más del ancho de la columna (4 caracteres, si mal no recuerdo).

Para solucionarlo, escribe tus cosas "OK / NOK" usando un número fijo de pestañas (5? 6 ?, pruébalo), luego regresa ( \ r ) sin una nueva línea y escriba su mensaje.

jpinto3912
fuente
5
Siempre existe el peligro de que una cadena sea más larga que una tabulación, lo que obliga a que la tabulación y el texto resultantes estén desalineados.
PP.
Realmente no ... primero escribe la pestaña OK / NOK, luego / r, ahora escribe la frase, ahora / n. La frase podría sobrescribir el OK / NOK. Pero tu camino es mucho mejor, no sabía de justificación negativa.
jpinto3912