Java printf para dar formato a los datos de salida

Vamos a ver como utilizar printf para dar formato a los datos que se imprimen por pantalla en Java.
Este problema se nos plantea por ejemplo cuando queremos mostrar un número de tipo float o double con un número determinado de decimales y no con los que por defecto muestra Java.

A partir de la versión Java 5 se incorporan los métodos format y printf que permiten aplicar un formato a la salida de datos por pantalla.
Ambos realizan la misma función, tienen exactamente el mismo formato y emulan la impresión con formato printf() de C.


Veamos primero varios ejemplos de printf en Java y después explicaremos en detalle la sintaxis de printf.

Si queremos mostrar el número 12.3698 de tipo double con dos decimales:

System.out.printf("%.2f %n", 12.3698);

El primer % indica que en esa posición se va a escribir un valor. El valor a escribir se encuentra a continuación de las comillas.
.2 indica el número de decimales.
La f indica que el número es de tipo float o double. En la tabla que aparece más adelante podeis ver todos los carateres de conversión para todos los tipos de datos.
%n indica un salto de línea. Equivale a \n. Con printf podemos usar ambos para hacer un salto de línea.

La salida por pantalla es:
12,37

Comprobamos que printf realiza un redondeo para mostrar los decimales indicados.
Lo más común será que tengamos el valor en una variable, en ese caso si queremos escribir el valor de n con tres decimales:

double n = 1.25036;
System.out.printf("%.3f %n", n);
Salida:
1,250

Para mostrar el signo + en un número positivo:
double n = 1.25036;
System.out.printf("%+.3f %n", n);
Salida:
+1.250

Si el número a mostrar es un entero se utiliza el caracter d:
int x = 10;
System.out.printf("%d %n", x);
Salida:
10

Para mostrarlo con signo:
int x = 10;
System.out.printf("%+d %n", x);
Salida:
+10

Para mostrar varias variables pondremos tantos % como valores vamos a mostrar. Las variables se escriben a continuación de las comillas separadas por comas:

double n = 1.25036;
int x = 10;
System.out.printf("n = %.2f x = %d %n", n, x);
Salida:
n = 1,25 x = 10

Cuando hay varias variables podemos indicar de cual de ellas es el valor a mostrar escribiendo 1$, 2$, 3$, ... indicando que el valor a mostrar es el de la primera variable que aparece a continuación de las comillas, de la segunda, etc.
La instrucción anterior la podemos escribir así:
System.out.printf("n = %1$.2f x = %2$d %n", n, x);

Este número es opcional, si no aparece se entenderá que el primer valor proviene de la primera variable, el segundo de la segunda, etc.

Si queremos mostrar el número 123.4567 y su cuadrado ambos con dos decimales debemos escribir:
double n = 123.4567;
System.out.printf("El cuadrado de %.2f es %.2f\n", n, n*n);
Salida:
El cuadrado de 123,46 es 15241,56

printf permite mostrar valores con un ancho de campo determinado. Por ejemplo, si queremos mostrar el contenido de n en un ancho de campo de 10 caracteres escribimos:

double n = 1.25036;
System.out.printf("%+10.2f %n", n);
Salida:
bbbbb+1.25
Donde cada b indica un espacio en blanco.
El 10 indica el tamaño en caracteres que ocupará el número en pantalla. Se cuentan además de las cifras del número el punto decimal y el signo si lo lleva. En este caso el número ocupa un espacio de 5 caracteres (3 cifras, un punto y el signo) por lo tanto se añaden 5 espacios en blanco al principio para completar el tamaño de 10.

Si queremos que en lugar de espacios en blancos nos muestre el número completando el ancho con ceros escribimos:
System.out.printf("%+010.2f %n", n);
Salida:
+000001.25

Más ejemplos de printf:

Mostrar el número 1.22 en un ancho de campo de 10 caracteres y con dos decimales.

double precio = 1.22;
System.out.printf("%10.2f", precio);

Salida:
bbbbbb1.22 
(el carácter b indica un espacio en blanco)
El número ocupa un espacio total de 10 caracteres incluyendo el punto y los dos decimales.

Mostrar la cadena "Total:" con un ancho de 10 caracteres y alineada a la izquierda:

System.out.printf("%-10s", "Total:");

Salida:
Total:bbbb

El caracter s indica que se va a mostrar una cadena de caracteres.
El signo - indica alineación a la izquierda.

Mostrar la cadena "Total:" con un ancho de 10 caracteres y alineada a la derecha:

System.out.printf("%10s", "Total:");

Salida:
bbbbTotal:

Al final puedes ver un ejemplo completo con distintos usos de printf.


Veamos ahora detenidamente la sintaxis de printf:

La sintaxis general de printf es:
printf (String de formato, Object … datos);

El String de formato es una cadena de caracteres que contiene:
- texto fijo que será mostrado tal cual
- especificadores de formato que determinan la forma en que se van mostrar los datos.
datos representa la información que se va a mostrar y sobre la que se aplica el formato. El número de datos que se pueden mostrar es variable.




Explicación de cada una de las partes que aparecen en la instrucción printf:

Especificadores de formato:

La sintaxis para los especificadores de formato de printf es:
%[posición_dato$][indicador_de_formato][ancho][.precision]carácter_de_conversión

Los elementos entre corchetes son opcionales.

posición_dato: indica la posición del dato sobre el que se va aplicar el formato. El primero por la izquierda ocupa la posición 1.

indicador_de_formato: es el conjunto de caracteres que determina el formato de salida. Los indicadores de formato de printf en Java son:


ancho: Indica el tamaño mínimo, medido en número de caracteres, que debe ocupar el dato en pantalla.

.precision: Indica el número de decimales que serán representados. Solo aplicable a datos de tipo float o double.

carácter_de_conversión: Carácter que indica cómo tiene que ser formateado el dato. Los más utilizados se muestran en la tabla.


Ejemplo completo con distintos usos de printf en Java:

public static void main(String[] args) {
     double q = 1.0/3.0;
     System.out.printf ("1.0/3.0 = %5.3f %n", q);
     System.out.printf ("1.0/3.0 = %7.5f %n", q);
     q = 1.0/2.0;
     System.out.printf ("1.0/2.0 = %09.3f %n", q);
     q = 1000.0/3.0;
     System.out.printf ("1000/3.0 = %7.1e h%n", q);
     q = 3.0/4567.0;
     System.out.printf ("3.0/4567.0 = %7.3e %n", q);
     q = -1.0/0.0;
     System.out.printf ("-1.0/0.0 = %7.2e %n", q);
     q = 0.0/0.0;
     System.out.printf ("0.0/0.0 = %5.2e %n", q);
     System.out.printf ("pi = %5.3f, e = %10.4f %n", Math.PI, Math.E);
     double r = 1.1;
     System.out.printf

            ("C = 2 * %1$5.5f * %2$4.1f, "+"A = %2$4.1f * %2$4.1f * %1$5.5f %n",Math.PI, r);
}



 Salida:

1.0/3.0 = 0,333
1.0/3.0 = 0,33333
1.0/2.0 = 00000,500
1000/3.0 = 3,3e+02 h
3.0/4567.0 = 6,569e-04
-1.0/0.0 = -Infinity
0.0/0.0 = NaN
pi = 3,142, e = 2,7183
C = 2 * 3,14159 * 1,1, A = 1,1 * 1,1 * 3,14159

Puedes encontrar más ejercicios para seguir practicando en este libro.


Contiene ejercicios resueltos sobre los conceptos básicos del lenguaje java: Declaración de variables, literales, tipos de datos, operadores, crear expresiones algebraicas correctas, etc.

Las soluciones de los ejercicios incluyen una explicación detallada sobre cómo se ha resuelto.

El contenido del libro es una recopilación de ejercicios realizados en mis clases de Programación en los ciclos formativos de grado superior Desarrollo de aplicaciones web y Desarrollo de aplicaciones multiplataforma.

41 comentarios:

  1. Me alegro de que os esté sirviendo de ayuda. Gracias a todos por los comentarios.

    ResponderEliminar
  2. Excelente aporte!!!!!!

    ResponderEliminar
  3. buenisimo gracias por la buena explicacion.

    ResponderEliminar
  4. excelente tratamiento, pero no entiendo muy bien el formato ....%n en la mascara, ¿no es mejor sustituir por salto de linea \n al estilo C?

    ResponderEliminar
    Respuestas
    1. Con printf se puede usar tando %n como \n para el salto de línea. La diferencia es que \n es el carácter nueva línea para los sistemas basados en Unix, mientras que en Windows se usa \r\n. Usando %n estamos diciendo a Java que utilce el carácter salto de línea del sistema.

      Eliminar
  5. Muy muy bueno, tenía serias dudas, pero ya me dejaste perfecto!!!

    ResponderEliminar
  6. Enrrique que libreria tengo que importar para usar el printf..es que yo trabajo con jcreator. Saludos y gracias

    ResponderEliminar
    Respuestas
    1. Hola Michel, para usar printf no es necesario importar ninguna librería. Saludos :)

      Eliminar
  7. hey bro!!! tengo un problema!!! si en vez de que me imprima ceros o "b" quiero que me imprima espacios en blanco como le hago???

    ResponderEliminar
  8. import java.util.Scanner;
    public class CampoE {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
    // TODO code application logic here
    System.out.println("se define Campo Electrico E en un punto en terminos de FUERZA "
    + "\n experimentada por una CARGA POSIITIVA cuando se coloca en dicho punto");
    String campo = "Campo";
    String carga = "Carga+";
    String fuerza = "Fuerza";
    Scanner in = new Scanner(System.in);
    String calcular;

    double f,q,e,resp;

    System.out.printf("que deseas Calcular %S %S %S %n",campo, fuerza, carga);
    calcular = in.nextLine();
    switch(calcular){
    case "campo": System.out.println("Calcularemos E ");
    System.out.printf("F= ");
    f= in.nextDouble();
    System.out.printf("q= ");
    q=in.nextDouble();
    resp=f/q;
    System.out.printf("%g E=" ,resp+" N/C");
    break;
    case "fuerza": System.out.println("Calcularemos F");
    System.out.printf("q= ");
    q=in.nextDouble();
    System.out.printf("E= ");
    e=in.nextDouble();
    resp=q*e;
    System.out.printf(" %g F=" ,resp+" N");
    break;
    case "carga": System.out.println("calcularemos q");break;
    default: System.out.println("variable no existente");break;

    }


    }
    }


    cual es mi error?
    no se si se deba a un error del IDE de Netbeans
    a la hora de introducir los datos en 'F' y 'q'
    le doy enter y no me realiza la operacion que indico en el programa y me arroja esto

    Exception in thread "main" java.util.IllegalFormatConversionException: g != java.lang.String
    at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4045)
    at java.util.Formatter$FormatSpecifier.printFloat(Formatter.java:2761)
    at java.util.Formatter$FormatSpecifier.print(Formatter.java:2708)
    at java.util.Formatter.format(Formatter.java:2488)
    at java.io.PrintStream.format(PrintStream.java:970)
    at java.io.PrintStream.printf(PrintStream.java:871)
    at fisica.CampoE.main(CampoE.java:40)

    por mas que busco no encuentro mi error ):

    ResponderEliminar
    Respuestas
    1. Hola Jose Antonio,
      El printf lo debes escribir así
      System.out.printf("E = %g N/C", resp);
      primero la cadena de formato y a continuación las variables
      Saludos

      Eliminar
    2. Muchas Gracias!
      son errores que sinceramente me cuestan mucho localizarlos
      GRACIAS

      Eliminar
  9. Respuestas
    1. Gracias por el comentario. Espero que sigas visitando el blog y que te siga siendo útil. Saludos

      Eliminar
  10. muchas gracias, me es muy util

    ResponderEliminar
  11. Muchas gracias, llevaba un rato buscando y esto ha sido lo más claro que he pillado en la red.
    Mil gracias!

    ResponderEliminar
  12. Me alegro de que os haya sido de ayuda. Gracias a todos por los comentarios.

    ResponderEliminar
  13. hola, tengo una cadena String = "-12.852" y quiero pasarla a este formato "999999999999.99-" osea 12 numeros enteros + punto + 2 decimales + signo a la derecha como puedo hacerlo? alguien que me ayude porfa ;)

    ResponderEliminar
  14. Hola yo quiero agregar 2 ceros a la izquierda de un numero entro así
    0012433
    y estoy poniendo asi System.out.printf("%02d %n", 12433);
    pero no me sale nada, solo sale así
    12433

    ResponderEliminar
    Respuestas
    1. David, lo correcto sería:

      System.out.printf("%07d %n", 12433);

      Resultado: 0012433

      en donde "7" es la cantidad de caracteres numéricos que quieres poner.

      Saludos

      Eliminar
  15. quiero que me salga el resultado 3.1416, pero me sale con así 3,1416
    double pi =3.141593;

    ResponderEliminar
    Respuestas
    1. Prueba con:

      import java.text.DecimalFormat;
      import java.text.DecimalFormatSymbols;

      public class Prueba {

      public static void main(String[] args) {
      DecimalFormatSymbols simbolos = new DecimalFormatSymbols();
      simbolos.setDecimalSeparator('.');
      DecimalFormat df = new DecimalFormat("####.####",simbolos);
      System.out.println (df.format (3.141593));
      // Imprime: 3.1416 y no 3,1416
      }
      }

      Eliminar
  16. Mil gracias por el aporte

    ResponderEliminar
  17. Una pregunta como haria el resultado de 1/3 con 2 enteros y 3 decimales

    ResponderEliminar
  18. Hola, muchas gracias por el post, me sirvió bastante para ampliar mi conocimiento acerca del printf() pero tengo un problema, resulta que tengo un algoritmo que menciona unos porcentajes, entonces quiero que imprima por ejemplo: El porcentaje es: 45.5%.
    La línea que tengo es:
    System.out.printf("El porcentaje es: %.1f\n", porcentaje);
    He tratado varias formas para insertar el '%' delante de la cantidad, pero no he conseguido más que errores :(
    Si me pudieses ayudar sería genial. Gracias

    ResponderEliminar
    Respuestas
    1. Hola Daniel, para que muestre el carácter % hay que escribir %%. Tu linea quedaría así:
      System.out.printf("El porcentaje es: %.1f%%\n", porcentaje);

      Eliminar
  19. public class numerosparimpar{
    public static void main(String[] args) {
    int i,sump=0,sumi=0;
    int np=0,ni=0;
    for(i=0;i<500;i++){
    sump=sump+(2*i+2);
    sumi=sumi+(2*i+1);
    }
    System.out.println(" NUMEROS PARES");
    int x;
    int y;
    for(int pp=1;pp<501;pp++)
    {
    x=pp*2;
    System.out.println(""+x);
    }
    System.out.println("NUMEROSIMPARES:");
    int j=1;
    while(j<1000)
    {
    System.out.println(""+j);
    j=j+2;
    np=np+1;
    ni=ni+1;
    }
    {
    System.out.println("SUMATORIA LOS NUMEROS PARES************* : "+sump);
    System.out.println("SUMATORIA LOSNUMEROS IMPARES*************: "+sumi);
    System.out.println("cantida LOS NUMEROS PARES*************: "+np);
    System.out.println("cantida LOS NUMEROS impares***********: "+ni);
    }
    }
    }
    como puedo hacer que aparezcan en dos columnas diferentes los par e impar

    ResponderEliminar
  20. Hola buenas noches, a mi me arroja este error y no me deja imprimir con forma

    The method printf(String, Object[]) in the type PrintStream is not applicable for the arguments (String, double)

    como lo puedo solucionar ?, me puedes ayudar por favor, gracias.

    ResponderEliminar
    Respuestas
    1. Muestra el código para ver donde puede estar el error

      Eliminar
    2. public class formatos {

      public static void main(String[] args) {

      double n = 1.25036;
      int x = 10;
      System.out.printf("n = %.2f x = %d %n", n, x);
      }

      }




      ese es, lo copio tal cual como esta en el ejemplo porque pensé que lo estaba haciendo mal, y da lo mismo, estoy utilizando Eclipse, no se si tengo que hacer algo adicional.
      no ejecuta, a la izquierda marca el error

      The method printf(String, Object[]) in the type PrintStream is not applicable for the arguments (String, double)

      Gracias

      Eliminar
    3. El código funciona bien, quizá el problema esté en la configuración de Eclipse o en el JDK que utilices.
      En este enlace hablan sobre este error https://stackoverflow.com/questions/7774428/the-method-printfstring-object-in-the-type-printstream-is-not-applicable-fo
      Espero que te ayude a solucionarlo.

      Eliminar
  21. guaoooo mil gracias de la mejor informacion que ahi en la red

    ResponderEliminar
  22. amigo una pregunta, en este ejemplo que pasas:
    Mostrar la cadena "Total:" con un ancho de 10 caracteres y alineada a la derecha:

    System.out.printf("%10s", "Total:");

    Salida:
    bbbbTotal:

    hay alguna manera de pasarle una variable en vez de un valor fijo?, es decir en vez de ponerle ese 10 : "%10s" pasarle una variable ?

    ResponderEliminar