NOMBRE¶
printf, fprintf, sprintf, vprintf, vfprintf, vsprintf - conversión de
  salida formateada
SINOPSIS¶
#include <stdio.h>
 
int printf(const char *format, ...);
 
int fprintf(FILE *stream, const char *format,
  ...);
 
int sprintf(char *str, const char *format,
  ...);
 
int snprintf(char *str, size_t size, const char
  *format, ...);
 
#include <stdarg.h>
 
int vprintf(const char *format, va_list ap);
 
int vfprintf(FILE *stream, const char *format,
  va_list ap);
 
int vsprintf(char *str, const char *format,
  va_list ap);
 
int vsnprintf(char *str, size_t size, const char
  *format, va_list ap);
DESCRIPCIÓN¶
Las funciones de la familia 
printf producen una salida de acuerdo a
  
format como se describe abajo. 
Printf y 
vprintf escriben
  su salida a 
stdout, el flujo de salida estándar. 
fprintf y
  
vfprintf escriben su salida al 
stream de salida dado.
  
sprintf, 
snprintf, 
vsprintf y 
vsnprintf escriben a
  una cadena de caracteres 
str.
Las funciones 
vprintf, 
vfprintf, 
vsprintf y
  
vsnprintf son equivalentes a las funciones 
printf,
  
fprintf, 
sprintf y 
snprintf, respectivamente, salvo en
  que se las llama con un va_list en lugar de con un número variable de
  argumentos. Estas funciones no llaman a la macro 
va_end. En
  consecuencia, el valor de 
ap queda indefinido después de la
  llamada. La propia aplicación debería llamar a 
va_end(ap)
  después.
Estas ocho funciones escriben la salida bajo el control de una cadena
  
format que especifica cómo los argumentos posteriores (o los
  argumentos accedidos mediante las facilidades de argumentos de longitud
  variables proporionadss por 
stdarg(3)) son convertidos para su salida.
Valor devuelto¶
En caso de éxito, estas funciones devuelven el número de caracteres
  impresos (no incluyendo el carácter `\0' usado para terminar la salida de
  cadenas). Las funciones 
snprintf y 
vsnprintf no escriben
  más de 
size bytes (incluyendo el carácter terminador '\0').
  Si la salida fue truncada debido a este límite el valor devuelto es el
  número de caracteres (no incluyendo el carácter final '\0') que se
  habrían escrito en la cadena final si hubiera habido suficiente espacio.
  De esta manera, un valor de retorno de 
size o más significa que la
  salida fue truncada. (Vea también debajo de OBSERVACIONES.) Si se
  encuentra un error de salida, se devuelve un valor negativo.
La cadena de formato es una cadena de caracteres que comienza y termina en su
  estado de cambios inicial, si lo hay. La cadena 
format está
  compuesta de cero o más directivas: caracteres ordinarios (no 
%)
  que se copian sin cambios al flujo de salida, e indicaciones de
  conversión, cada uno de las cuales produce la búsqueda de cero o
  más argumentos posteriores. Cada especificación de conversión
  se introduce mediante el carácter 
% y termina con un 
indicador
  de conversión. En medio puede haber (en este orden) cero o más
  
opciones, una 
anchura de campo opcional mínima, una
  
precisión opcional y un 
modificador de longitud opcional.
 
Los argumentos se deben corresponder adecuadamente (después de la
  promoción de tipos) con el indiciador de conversión. Por defecto,
  los argumentos se usan en el orden dado, donde cada `*' y cada indicador de
  conversión pregunta por el siguiente argumento (y es un error si se dan
  de forma insuficiente muchos argumentos). También se puede especificar
  explícitamente qué argumento se toma, en cada lugar donde se
  necesite un argumento, escribiendo `%m$' en lugar de `%' y `*m$' en lugar de
  `*', donde el entero decimal m denota la posición en la lista de
  argumentos del argumento deseado, empezando por 1. Por tanto,
	printf("%*d", width, num);
 
y
	printf("%2$*1$d", width, num);
 
son equivalentes. El segundo estilo permite referencias repetidas al mismo
  argumento. El estándar C99 no incluye el estilo usando caracteres `$',
  que proviene de `the Single Unix Specification'. Si se utiliza el estilo con
  `$', debe ser usado para todas las conversiones tomando un argumento y todos
  los argumentos de anchura y precisión, pero puede mezclarse con formatos
  `%%' que no consumen ningún argumento. No puede haber huecos en los
  números de los argumentos especificados usando `$'; por ejemplo, si se
  especifican los argumentos 1 y 3, el argumento 2 debe ser también
  especificado en algún lugar en la cadena de formato.
 
Para alguna conversión numérica se usa un carácter radical
  (`punto decimal') o carácter separador de miles. El carácter real
  usado depende de la parte LC_NUMERIC de la localización. La
  localizacíon POSIX usa `.' como carácter radical y no posee un
  carácter separador de miles. Por tanto,
	printf("%'.2f", 1234567.89);
 
produce `1234567.89' en la localización POSIX, `1234567,89' en la
  localización nl_NL, y `1.234.567,89' en la localización da_DK.
Los caracteres de opción¶
El carácter % va seguido por cero o más de las siguientes opciones:
  - #
 
  - El valor debe ser convertido a un ``formato alternativo''.
      Para las conversiones o, el primer carácter de la cadena de
      salida se hace 0 (prefijando un cero si ya era distinto de cero). Para las
      conversiones x y X, la cadena `0x' (o `0X' para conversiones
      X ) precede a los resultados que son distintos de 0. Para las
      conversiones a, A, e, E, f, F,
      g, y G, el resultado contendrá un punto decimal,
      aún si ningún dígito lo sigue (normalmente, sólo
      aparece un punto decimal en el resultado de aquellas conversiones que son
      seguidas de algún dígito). Para las conversiones g y
      G, en el resultado no se eliminan los ceros del final, como
      ocurriría en otro caso. Para otras conversiones, el resultado es
      indefinido.
 
  - 0
 
  - El valor se debe rellenar con ceros. Para las conversiones
      d, i, o, u, x, X, a,
      A, e, E, f, F, g, y G ,
      el valor convertido es rellenado a la izquierda con ceros en vez de
      blancos. Si las banderas 0 y - aparecen a la vez, la bandera
      0 es ignorada. Si en una conversión numérica
      (d, i, o, u, x, y X), se
      indica una precisión, la bandera 0 se ignora. Para otras
      conversiones, el resultado es indefinido.
 
  - -
 
  - El valor convertido es justificado a la izquierda sobre el
      límite del campo. (Por defecto, la justificación es a la
      derecha). Excepto para conversiones n, el valor convertido es
      rellenado a la derecha con blancos, en vez de a la izquierda con blancos o
      ceros. Un - sobreescribe un 0 si se indican ambos.
 
  - 
  
  
 
  - (un espacio) Se debe dejar un espacio en blanco delante de
      un número positivo (o cadena vacía) producido por una
      conversión con signo.
 
  - +
 
  - Siempre se colocará el signo (+ o -) delante de un
      número producido por una conversión con signo. Por omisión,
      sólo se usa el signo para los números negativos. Un +
      sobreescribe un espacio si se usan ambos.
 
Los cinco carácteres de opción anteriores se definen en el
  estándar C. SUSv2 especifica un carácter de opción adicional.
  - '
 
  - Para una conversión decimal (i,
      d, u, f, F, g, G) la salida se
      va a agrupar con caracteres de separación de miles si la
      información de localización así lo indica. Dese cuenta que
      muchas versiones de gcc no pueden analizar esta opción y
      producirán una advertencia. SUSv2 no incluye %'F.
 
glibc 2.2 añada un nuevo carácter de opción adicional.
  - I
 
  - Para una conversión decimal entera (i,
      d, u) la salida utiliza los dígitos de salida
      alternativos de la localización, si hay (por ejemplo, dígitos
      árabes). Sin embargo, no incluye ninguna definición de
      localización con tales dígitos de salida outdigits
      definidos.
 
La anchura de campo¶
Una cadena de dígitos decimales opcional (con un primer dígito
  distinto de cero) que especifica una anchura de campo mínimo. Si el valor
  convertido tiene menos caracteres que la anchura del campo, se rellenará
  con espacios a la izquierda (o a la derecha, si se da la opción de
  justificación a la izquierda). En lugar de una cadena de dígitos
  decimales se puede escribir `*' o `*m$' (para algún entero decimal m)
  para especificar que la anchura del campo se proporciona en el siguiente
  argumento o en el m-ésimo argumento, respectivamente, que debe ser de
  tipo 
int. Una anchura de campo negativa se toma como una opción
  `-' seguida por una anchura de campo positiva. En ningún caso, una
  anchura de campo inexistente o pequeña hace que el campo se trunque. Si
  el resultado de la conversión es más ancho que la anchura del campo,
  el campo se expande para contener el resultado de la conversión.
La precisión¶
Una precisión opcional, indicada por un punto (`.') seguido por una cadena
  de dígitos también opcional. En lugar de una cadena de dígitos
  decimales se puede escribir `*' o `*m$' (para algún entero decimal m)
  para especificar que la precisión se da en el siguiente argumento o en el
  m-ésimo argumento, respectivamente, que debe ser de tipo 
int. Si
  la precisión se da como un simple `.', o si la precisión es
  negativa, la precisión se toma como cero. Esto da el número
  mínimo de dígitos que deben aparecer en las conversiones 
d,
  
i, 
o, 
u, 
x, y 
X, el número de
  dígitos que deben aparacer tras el carácter radical en las
  conversiones 
a, 
A, 
e, 
E, 
f y 
F, el
  máximo número de dígitos significativos para las conversiones
  
g y 
G, o el máximo número de caracteres a imprimir de
  una cadena en las conversiones 
s y 
S.
El indicador de longitud¶
Aquí, `conversión entera' significa una conversión 
d,
  
i, 
o, 
u, 
x, o 
X.
  - hh
 
  - La siguiente conversión entera se corresponde con un
      argumento signed char o unsigned char, o la siguiente
      conversión n se corresponde a un puntero a un argumento
      signed char .
 
  - h
 
  - La siguiente conversión entera se corresponde con un
      argumento short int o unsigned short int, o que la siguiente
      conversión n corresponde a un puntero a un argumento short
      int.
 
  - l
 
  - (ele) La siguiente conversión entera corresponde a un
      argumento long int o unsigned long int, o que la siguiente
      conversión n corresponde a un puntero a un argumento long
      int o que la siguiente conversión c corresponde a un
      argumento wint_t, o que la siguiente conversión s
      corresponde a un puntero a un argumento wchar_t.
 
  - ll
 
  - (ele-ele). La siguiente conversión entera corresponde
      a un argumento long long int o unsigned long long int , o
      que la siguiente conversión n corresponde a un puntero a un
      argumento long long int.
 
  - L
 
  - La siguiente conversión a, A, e,
      E, f, F, g, o G corresponde a un
      argumento long double. (C99 permite %LF, pero SUSv2 no.)
 
  - q
 
  - (`cuadruple'. BSD 4.4 y Linux libc5 sólo. No usar.)
      Esto es un sinónimo de ll.
 
  - j
 
  - La siguiente conversión entera corresponde a un
      intmax_t o uintmax_t.
 
  - z
 
  - La siguiente conversión entera corresponde a un
      argumento size_t o ssize_t. (Linux libc5 tiene Z con
      este significado. No lo use.)
 
  - t
 
  - La siguiente conversión entera corresponde a un
      argumento ptrdiff_t.
 
SUSv2 sólo conoce los indicadores de longitud 
h (en 
hd,
  
hi, 
ho, 
hx, 
hX, 
hn), 
l (en
  
ld, 
li, 
lo, 
lx, 
lX, 
ln, 
lc,
  
ls) y 
L (en 
Le, 
LE, 
Lf, 
Lg,
  
LG).
 
El indicador de conversión¶
Un carácter que especifica el tipo de conversión a ser aplicado. Los
  indicadores de conversión y sus significados son:
  - d,i
 
  - El argumento int se convierte a la notación
      decimal con signo. La precisión, si la hay, da el número
      mínimo de dígitos que deben aparecer. Si el valor convertido
      necesita menos dígitos, se rellena a la izquierda con ceros. La
      precisión por omisión es 1. Cuando se imprime 0 con una
      precisión explícita 0, la salida es la cadena vacía.
 
  - o,u,x,X
 
  - El argumento unsigned int se convierte a un octal
      sin signo (o, a decimal sin signo (u, a a
      notación hexadecimal sin signo (x y X). Las
      letras abcdef son usadas para conversiones x. Las letras
      ABCDEF son usadas para conversiones X. La precisión, si
      se ha indicado alguna, da el mínimo número de dígitos que
      deben aparecer. Si el valor convertido requiere menos dígitos,
      éste es rellenado a la izquierda con ceros. La precisión por
      omisión es 1. Cuando se imprime 0 con una precisión
      explícita 0, la salida es la cadena vacía.
 
  - e,E
 
  - El argumento double es redondeado y convertido al
      formato [-]d.ddde*(Pmdd donde hay un dígito
      delante del carácter del punto decimal y el número de
      dígitos después de éste es igual a la precisión. Si no
      se indica precisión, ésta es tomada como 6. Si la precisión
      es cero, no aparece el carácter de punto decimal. Una conversión
      E usa la letra E ( en vez de e) para introducir el
      exponente. El exponente siempre contiene al menos dos dígitos. Si el
      valor es cero, el exponente es 00.
 
  - f,F
 
  - El argumento double es redondeado y convertido a una
      notación decimal del estilo [-]ddd.ddd, donde el
      número de dígitos después del carácter del punto
      decimal es igual a la especificación de la precisión. Si no se
      indica precisión, ésta es tomada como 6. Si la precisión es
      explícitamente cero, no aparece el carácter del punto decimal.
      Si aparece un punto decimal, al menos aparece un dígito delante de
      él.
    
 
    (SUSv2 no conoce F y dice que deben estar disponibles reprentaciones
      como cadenas de caracteres para infinito y NaN (Not a Number, no es un
      número). El estándar C00 especifica `[-]inf' o `[-]infinity'
      para el infinito y una cadena que comienza por `Nan' para NaN, en el caso
      de una conversión f, y `[-]INF' o `[-]INFINITY' o `NAN*' en el
      caso de una conversión F.) 
  - g,G
 
  - El argumento double es convertido al estilo de
      f o e (o F o E para conversiones G ).
      La precisión especifica el número de dígitos
      significativos. Si no se indica precisión, se dan 6 dígitos. Si
      la precisión es cero, ésta es tratada como 1. Se utiliza el
      formato de e si el exponente de su conversión es menor que -4
      o más grande o igual a la precisión. Los ceros finales se
      eliminan de la parte fraccional del resultado. Un punto decimal sólo
      aparece si es seguido de al menos un dígito.
 
  - a,A
 
  - (C99. No en SUSv2) Para una conversión a, el
      argumento double se convierte a notación hexadecimal (usando
      las letras abcdef) según el estilo
      [-]0xh.hhhhp*(Pmd. Para una conversión
      A se usan el prefijo 0X, las letras ABCDEF y el separador de
      exponente P. Hay un dígito hexadecimal antes del punto decimal
      y el número de dígitos tras él es igual a la
      precisión. La precisión por omisión es suficiente para una
      representación exacta del valor si existe una representación
      exacta en base 2 y, en otro caso, es suficientemente grande para
      distinguir valores de tipo double. El dígito antes del punto
      decimal queda sin especificar para números no normalizados y distinto
      de cero pero, en cualquier caso, sin especificar para números
      normalizados.
 
  - c
 
  - Si no está presente un modificador l, el
      argumento int es convertido a un unsigned char, y se escribe
      el carácter resultante. Si está presente un modificador
      l, el argumento wint_t (carácter ancho) se convierte a
      una secuencia multibyte llamando a la función wcrtomb, con un
      estado de conversión que comienza en el estado inicial, y se escribe
      la cadena multibyte resultante.
 
  - s
 
  - Si no está presente un modificador l: se espera
      que el argumento const char * sea un puntero a un vector (array) de
      tipo carácter (puntero a una cadena de caracteres). Se escriben
      caracteres del array hasta (pero no incluyendo) un carácter
      terminador NUL. Si se especifica una precisión, no se escriben
      más caracteres del número especificado. Si se da una
      precisión, no es necesario que aparezca ningún carácter
      nulo. Si no se especifica precisión, o es mayor que el tamaño de
      la cadena, la cadena debe contener un carácter de terminación
      NUL. Si está presente un modificador l: se espera que
      el argumento const wchar_t * sea un puntero a un vector de
      caracteres anchos. Los caracteres anchos del array se convierten a
      caracteres multibyte (cada uno llamando a la función wcrtomb,
      con un estado de conversión que comienza en el estado inicial antes
      del primer carácter ancho) incluyendo el carácter ancho nulo
      terminador. Los caracteres multibyte resultantes se escriben hasta llegar
      (pero sin incluir) el byte nulo terminador. Si se especifica una
      precisión, no se escriben más bytes de los indica el
      número, aunque no se escribe ningún carácter multibyte
      parcial. Advierta que la precisión determina el número de
      bytes escritos, no el número de caracteres anchos o
      posiciones de pantalla. El vector debe contener un carácter
      ancho nulo terminador, a menos que se de una precisión que sea tan
      pequeña que el número de bytes escritos la exceda antes de
      llegar al final del vector.
 
  - C
 
  - (No en C99, pero sí en SUSv2.) Sinónimo de
      lc. No usar.
 
  - S
 
  - (No en C99, pero sí en SUSv2.) Sinónimo de
      ls. No usar.
 
  - p
 
  - El argumento de tipo puntero void * se imprime en
      hexadecimal (como si se hubiera indicado %#x o %#lx).
 
  - n
 
  - El número de caracteres escritos hasta ahora se guarda
      en el entero indicado por el argumento de tipo puntero int * (o una
      variante suya). No se convierte ningún argumento.
 
  - %
 
  - Se escribe un `%'. No se convierte ningún argumento.
      La especificación completa de conversión es `%%'.
 
EJEMPLOS¶
Para imprimir pi con cinco cifras decimales:
#include <math.h>
#include <stdio.h>
fprintf(stdout, "pi = %.5f\n", 4 * atan(1.0));
 
Para imprimir una fecha y una hora de la forma `Sunday, July 3, 10:02', donde
  
weekday y 
month son punteros a cadenas:
#include <stdio.h>
fprintf(stdout, "%s, %s %d, %.2d:%.2d\n",
	weekday, month, day, hour, min);
 
Muchos países usan el orden día-mes-año. Por tanto, una
  versión internacionalizada debe ser capaz de mostrar los argumentos en el
  orden indicado por el formato:
#include <stdio.h>
fprintf(stdout, formato,
	diasemana, mes, día, hora, min);
 
donde 
formato depende de la localización y puede permutar los
  argumentos. Con el valor
"%1$s, %3$d. %2$s, %4$d:%5$.2d\n"
 
se podría obtener `sonntag, 3. Juli, 10:02'.
Para reservar una cadena de 128 bytes e imprimir dentro de ella: Para reservar
  una cadena suficientemente grande e imprimir dentro de ella: (código
  correcto tanto para glibc 2.0 como glibc 2.1):
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
char *
construye_mensaje(const char *fmt, ...) {
	/* Suponemos que no necesitamos más de 100 bytes. */
	int n, size = 100;
	char *p;
	va_list ap;
	if ((p = malloc (size)) == NULL)
		return NULL;
	while (1) {
		/* Intenta imprimir en el espacio reservado. */
		va_start(ap, fmt);
		n = vsnprintf (p, size, fmt, ap);
		va_end(ap);
		/* Si ha funcionado, devuelve la cadena. */
		if (n > -1 && n < size)
			return p;
		/* Si no, inténtalo de nuevo con más espacio. */
		if (n > -1)    /* glibc 2.1 */
			size = n+1; /* exactamente lo que se necesita */
		else           /* glibc 2.0 */
			size *= 2;  /* el doble del tamaño anterior*/
		if ((p = realloc (p, size)) == NULL)
			return NULL;
	}
}
 
 
OBSERVACIONES¶
La implementación de glibc de las funciones 
snprintf y
  
vsnprintf es conforme con el estándar C99, es decir, se comporta
  como se describe arriba, desde la versión 2.1 de glibc. Hasta la
  versión 2.0.6 de glibc devolvían -1 cuando la salida era truncada.
Las funciones 
fprintf, 
printf, 
sprintf, 
vprintf,
  
vfprintf, y 
vsprintf están conforme a ANSI X3.159-1989
  (``ANSI C'') e ISO/IEC 9899:1999 (``ISO C99''). Las funciones 
snprintf
  y 
vsnprintf están conforme a ISO/IEC 9899:1999.
Teniendo en cuenta el valor devuelto pr 
snprintf, SUSv2 y el
  estándar C99 se contradicen: cuando 
snprintf se llama con
  
size=0, SUSv2 estipula un valor devuelto sin especificar menor que 1,
  mientras que C99 permite que 
str sea NULL en este caso y da el valor
  devuelto (como siempre) como el número de caracteres que habrían
  sido escritos en el caso de que la cadena de salida hubiera sido lo
  suficientemente grande.
La libc4 de Linux reconoce las cinco opciones estándares de C. Reconoce los
  modificadores de longitud h, l y L, y las conversiones cdeEfFgGinopsuxX, donde
  F es un sinónimo de f. Adicionalmente, acepta D, O y U, como
  sinónimos de ld, lo y lu. (Esto es malo y provocó serios fallos
  más tarde, cuando desapareció el soporte para %D). No reconoce un
  carácter radical dependiente de la localización, ni un separador de
  miles, ni NaN ni infinito, ni %m$ ni *m$.
La biblioteca libc5 de Linux reconoce las cinco opciones estándares de C y
  la opción ', locale, %m$ y *m$. Reconoce los modificadores de longitud h,
  l, L, Z y q, pero acepta L y q, ambos para valores 
long double y
  
long long integer (esto es un fallo). Ya no reconoce más FDOU,
  pero añade un nuevo carácter de conversión 
m, que
  produce 
strerror(errno).
glibc 2.0 añade los caracteres de conversión C y S.
glibc 2.1 añade los modificadores de longitud hh, j, t y z, y los
  caracteres de conversión a y A.
glibc 2.2 añade el carácter de conversión F con la semántica
  de C99, y el carácter de opción I.
HISTORIA¶
Unix V7 define las tres rutinas 
printf, 
fprintf, 
sprintf, y
  posee la opción -, la anchura o precisión *, el modificador de
  longitud l, las conversiones doxfegcsu, y también D, O, U y X como
  sinónimos de ld, lo, lu y lx. Esto todavía es cierto para BSD 2.9.1,
  pero BSD 2.10 tiene las opciones #, + y <space> y ya no menciona D, O, U
  y X. BSD 2.11 tiene 
vprintf, 
vfprintf, 
vsprintf, y
  advierte de no usar D, O, U y X. BSD 4.3 Reno tiene la opción 0, los
  modificadores de longitud h y L, las conversiones n, p, E, G, X (con el
  significado actual) y hace obsoletas D, O y U. BSD 4.4 introduce las funciones
  
snprintf y 
vsnprintf, y el modificador de longitud q. FreeBSD
  también posee las funciones 
asprintf y 
vasprintf, que
  reservan un buffer los suficientemente largo para 
sprintf. En glibc
  están las funciones 
dprintf y 
vdprintf que imprimen en un
  descriptor de fichero en lugar de un flujo.
FALLOS¶
Ya que 
sprintf y 
vsprintf asumen una cadena de longitud
  arbitraria, los invocadores deben tener cuidado de no sobrepasar el espacio
  real, lo que a menudo resulta imposible de garantizar. Advierta que las
  longitudes de las cadenas producidas dependen de la localización y que
  son difíciles de predecir. Use 
snprintf y 
vsnprintf en su
  lugar (o 
asprintf y 
vasprintf).
La biblioteca libc4.[45] de Linux no posee la función 
snprintf, pero
  proporciona una libbsd que contiene una función 
snprintf
  equivalente a 
sprintf, es decir, una que ignora el argumento
  
size. Por tanto, el uso de 
snprintf con las primeras libc4
  conduce a serios problemas de seguridad.
Fragmentos de código como 
printf(foo); indican a
  menudo un fallo, puesto que 
foo puede contener un carácter %. Si
  
foo proviene de la entrada del usuario, puede contener %n, provocando
  que la llamada 
printf escriba en memoria y creando un agujero de
  seguridad.
 
VÉASE TAMBIÉN¶
printf(1), 
asprintf(3), 
dprintf(3), 
wcrtomb(3),
  
wprintf(3), 
scanf(3), 
locale(5)