Cuando trabajamos con printf en C, podemos ir mucho más allá de simplemente imprimir variables en pantalla. Aunque ya sabemos que printf procesa una cadena de caracteres y reconoce los placeholders como %i para imprimir enteros, existen modificadores que nos permiten controlar con precisión cómo se muestra la información, facilitando la lectura y el formato de la salida.
Una de las funcionalidades más curiosas es la posibilidad de cambiar el orden en que se imprimen los parámetros. Normalmente, el primer placeholder corresponde al primer argumento, el segundo al segundo, y así sucesivamente. Pero si queremos, podemos especificar explícitamente qué argumento imprimir en cada placeholder usando un número seguido de un signo de dólar, como %2$i o %1$i. Esto nos permite, por ejemplo, imprimir primero el segundo argumento y luego el primero, algo que puede ser útil en ciertos contextos, aunque no es muy común.
En cuanto a la alineación y el espacio que ocupa cada valor impreso, podemos indicar un ancho mínimo para el campo donde se mostrará la variable. Por ejemplo, si ponemos %15i, le decimos a printf que reserve 15 caracteres para imprimir ese número, alineándolo a la derecha y rellenando con espacios a la izquierda si el número es más corto. Esto es especialmente útil cuando imprimimos varias líneas con datos para que queden alineados y sean más legibles.
Si queremos que la alineación sea hacia la izquierda, basta con poner un signo menos antes del número, como %-15i. En este caso, el número se imprime alineado a la izquierda y los espacios sobrantes quedan a la derecha. Además, si en lugar de espacios queremos rellenar con ceros, podemos usar un cero delante del ancho, por ejemplo %015i, y así el espacio sobrante se rellena con ceros a la izquierda.
Cuando trabajamos con números flotantes, estos modificadores también funcionan, pero podemos añadir otro que controla la precisión decimal. Por ejemplo, %10.2f indica que queremos que el número ocupe un total de 10 caracteres, de los cuales 2 serán para la parte decimal. El punto decimal cuenta como un carácter más, por lo que la parte entera tendrá el espacio restante. Esto también hace que el número se redondee a la cantidad de decimales indicada, algo muy útil para mostrar precios o medidas con un formato uniforme.
Si solo queremos controlar la cantidad de decimales sin preocuparnos por el ancho total, podemos usar simplemente %.2f, y printf imprimirá el número con dos decimales, sin limitar el espacio total que ocupa.
Estos mismos conceptos de ancho y alineación también aplican a cadenas de caracteres. Por ejemplo, %20s imprimirá una cadena reservando 20 caracteres, alineándola a la derecha, mientras que %-20s la alineará a la izquierda.
Para controlar la presencia del signo en números, existe el modificador +. Si lo usamos, como en %+i, printf imprimirá siempre el signo, incluso para números positivos. Por defecto, los números negativos ya muestran el signo menos, pero los positivos no muestran el signo más a menos que lo indiquemos con este modificador. Podemos combinarlo con la alineación para que el signo aparezca y el número quede alineado a la izquierda, por ejemplo %+-10i.
En el ámbito de la programación de bajo nivel o cuando trabajamos con valores hexadecimales, printf nos permite imprimir números en base 16 usando %x. Si queremos que la salida incluya el prefijo 0x que indica que es hexadecimal, podemos usar el modificador #, así: %#x. Esto imprimirá, por ejemplo, 0x3039 en lugar de solo 3039.
Además, podemos combinar este modificador con el ancho y el relleno con ceros, como %#08x, que imprimirá el número hexadecimal con al menos 8 caracteres, rellenando con ceros a la izquierda y manteniendo el prefijo 0x. Hay que tener en cuenta que el prefijo cuenta dentro del ancho total, por lo que si queremos que el número hexadecimal tenga 8 caracteres sin contar el 0x, debemos ajustar el ancho sumando 2, por ejemplo %#010x.
Por último, es importante entender que algunos modificadores que parecen parte del comando en realidad son modificadores de tipo. Por ejemplo, la letra L en %ld o %li indica que la variable es un long int, no un int. Esto es un modificador que cambia el tipo de dato que printf espera para ese placeholder.
De manera similar, existe el modificador h que indica que la variable es un short int. Por ejemplo, %hd imprimirá un número interpretado como un entero corto de 16 bits. Esto puede provocar que, si el valor original es más grande, se produzca un overflow y el número impreso sea negativo o diferente, debido al casteo implícito.
Estos modificadores nos permiten adaptar la salida de printf a diferentes tipos de datos y formatos, evitando tener que escribir código adicional para formatear la salida manualmente y facilitando la presentación de datos en programas en C.