Sintaxis de especificación de formato: funciones printf y wprintf

Las distintas funciones printf y wprintf toman una cadena de formato y argumentos opcionales y generan una secuencia de caracteres con formato para la salida. La cadena de formato contiene cero o más directivas, que son caracteres literales para la salida o especificaciones de conversión codificadas que describen cómo dar formato a un argumento en la salida. En este artículo se describe la sintaxis utilizada para codificar las especificaciones de conversión en la cadena de formato. Para obtener una lista de estas funciones, vea E/S de secuencia.

Una especificación de conversión consta de campos opcionales y obligatorios con este formato:

%[marcas][ancho][.precisión][tamaño]tipo

Cada campo de la especificación de conversión es un carácter o un número que indica una opción de formato o un especificador de conversión. El campo obligatorio tipo especifica el tipo de conversión que se aplicará a un argumento. Los campos opcionales de marcas, ancho y precisión controlan otros aspectos de formato, como espacios iniciales o ceros, justificación y precisión mostrada. El campo tamaño especifica el tamaño del argumento consumido y convertido.

La especificación de conversión básica solo contiene el signo de porcentaje y un carácter para tipo. Por ejemplo, %s especifica una conversión de cadena. Para imprimir un carácter de signo de porcentaje, use %%. Si un signo de porcentaje va seguido de un carácter que no tiene ningún significado como campo de formato, se invoca el controlador de parámetros no válidos. Para obtener más información, vea Validación de parámetros.

Importante

Para garantizar la seguridad y la estabilidad, asegúrese de que las cadenas de especificación de conversión de formato no estén definidas por el usuario final. Por ejemplo, imagine un programa que solicita al usuario que escriba un nombre y almacena la entrada en una variable de cadena denominada user_name. Para imprimir user_name, no haga esto nunca:

printf( user_name ); /* Danger! If user_name contains "%s", program will crash */

En lugar de ello, haga esto:

printf( "%s", user_name );

Nota

En Visual Studio 2015, la familia de funciones printf y scanf se declararon como inline y se movieron a los encabezados <stdio.h> y <conio.h>. Si va a migrar código antiguo, es posible que vea LNK2019 en conexión con estas funciones. Para obtener más información, consulte Historial de cambios en Visual C++ 2003 - 2015.

Especificador de conversión de tipo

El carácter del especificador de conversión tipo especifica si el argumento correspondiente debe interpretarse como un carácter, una cadena, un puntero, un entero o un número de punto flotante. El carácter de tipo es el único campo de especificación de conversión necesario y aparece después de los campos opcionales.

Los argumentos que siguen a la cadena de formato se interpretan según el carácter de tipo correspondiente y el prefijo de tamaño opcional. Las conversiones de tipos de caracteres char y wchar_t se especifican mediante c o C y las cadenas de caracteres de byte único y multibyte o de carácter ancho se especifican mediante s o S, según la función de formato que se esté usando. Los argumentos de caracteres y de cadena que se especifican mediante el uso de c y s se interpretan como char y char* en la familia de funciones printf o como wchar_t y wchar_t* en la familia de funciones wprintf. Los argumentos de caracteres y de cadena que se especifican mediante el uso de C y S se interpretan como wchar_t y wchar_t* en la familia de funciones printf o como char y char* en la familia de funciones wprintf. Este comportamiento es específico de Microsoft. Por motivos históricos, las wprintf funciones usan c y s hacen referencia a wchar_t caracteres y C especifican S caracteres estrechos.

Los tipos de enteros como short, int, long, long long y sus variantes unsigned se especifican mediante d, i, o, u, x y X. Los tipos de punto flotante como float, double y long double se especifican mediante a, A, e, E, f, F, g y G. De forma predeterminada, y a menos que los modifique un prefijo de tamaño, los argumentos de entero se convierten en el tipo int y los argumentos de punto flotante se convierten en double. En los sistemas de 64 bits, es int un valor de 32 bits; por lo tanto, los enteros de 64 bits se truncarán cuando tengan formato para la salida a menos que se use un prefijo de tamaño de ll o I64 . Los tipos de puntero que se especifican mediante p usan el tamaño de puntero predeterminado para la plataforma.

Nota

Microsoft-specific:
El carácter de tipo Z, así como el comportamiento de los caracteres de tipo c, C, s y S cuando se usan con las funciones printf y wprintf, son extensiones de Microsoft. El estándar ISO C usa c y s sistemáticamente para cadenas y caracteres estrechos, así como C y S para cadenas y caracteres anchos, en todas las funciones de formato.

Caracteres del campo de tipo

Carácter de tipo Argumento Formato de salida
c Carácter Cuando se usa con funciones printf, especifica un carácter de byte único; cuando se usa con funciones wprintf, especifica un carácter ancho.
C Carácter Cuando se usa con funciones printf, especifica un carácter ancho; cuando se usa con funciones wprintf, especifica un carácter de byte único.
d Entero Entero decimal con signo.
i Entero Entero decimal con signo.
o Entero Entero octal sin signo.
u Entero Entero decimal sin signo.
x Entero Entero hexadecimal sin signo; usa "abcdef".
X Entero Entero hexadecimal sin signo; usa "ABCDEF".
e Punto flotante Valor con signo que tiene el formato [-]d.dddde[|-+]dd[d], donde d es un dígito decimal, dddd es uno o más dígitos decimales según la precisión especificada, o seis de forma predeterminada, y dd[d] es de dos o tres dígitos decimales según el formato de salida y el tamaño del exponente.
E Punto flotante Es idéntico al formato de e, salvo que el exponente se introduce mediante E en lugar de e.
f Punto flotante Valor con signo que tiene el formato [-]dddd.dddd, donde dddd es uno o varios dígitos decimales. El número de dígitos que hay delante del separador decimal depende de la magnitud del número y el número de dígitos que hay detrás del separador decimal depende de la precisión solicitada, seis de forma predeterminada.
F Punto flotante Idéntico al f formato, excepto que la salida infinito y NaN están en mayúsculas.
g Punto flotante Los valores con signo se muestran en formato f o e, lo que sea más conciso para el valor y la precisión especificados. El formato e solo se usa cuando el exponente del valor es menor que -4 o mayor o igual que el argumento precision. Los ceros a la derecha se truncan y el separador decimal tan solo aparece si va seguido de uno o más dígitos.
G Punto flotante Es idéntico al formato de g, salvo que el exponente se introduce mediante E en lugar de e (cuando corresponda).
a Punto flotante El valor de punto flotante de precisión doble con signo hexadecimal que tiene el formato [-]0xh.hhhhp[|-+]dd, donde h.hhhh son los dígitos hexadecimales (con letras minúsculas) de la mantisa y dd son uno o más dígitos para el exponente. La precisión especifica el número de dígitos que se muestran después del punto.
A Punto flotante Valor de punto flotante de doble precisión hexadecimal con signo que tiene la forma [-]0Xh.hhhhP[|-+]dd, donde h.hhhh son los dígitos hexadecimales (mediante letras mayúsculas) de la mantisa y dd son uno o más dígitos para el exponente. La precisión especifica el número de dígitos que se muestran después del punto.
n Puntero para entero Número de caracteres que se han escrito correctamente en el flujo o búfer. Este valor se almacena en el entero cuya dirección se indica como argumento. El tamaño del entero al que se apunta se puede controlar mediante un prefijo de especificación del tamaño de argumento. El especificador n está deshabilitado de forma predeterminada; para información, consulte la nota de seguridad importante.
p Tipo de puntero Muestra el argumento como dirección de dígitos hexadecimales.
s String Cuando se usa con funciones printf, especifica una cadena de caracteres de byte único o multibyte; cuando se usa con funciones wprintf, especifica una cadena de carácter ancho. Los caracteres se muestran hasta el primer carácter nulo o hasta que se alcanza el valor de precisión.
S String Cuando se usa con funciones printf, especifica una cadena de carácter ancho; cuando se usa con funciones wprintf, especifica una cadena de caracteres de byte único o multibyte. Los caracteres se muestran hasta el primer carácter nulo o hasta que se alcanza el valor de precisión.
Z Estructura ANSI_STRING o UNICODE_STRING VS 2013 y versiones anteriores
Cuando la dirección de una estructura ANSI_STRING o UNICODE_STRING se pasa como argumento, muestra la cadena contenida en el búfer al que apunta el campo Buffer de la estructura. Use un prefijo del modificador tamaño de w para especificar un argumento UNICODE_STRING, por ejemplo, %wZ. El campo Length de la estructura debe establecerse en la longitud de la cadena expresada en bytes. El campo MaximumLength de la estructura debe establecerse en la longitud del búfer expresada en bytes.

Tiempo de ejecución universal de C (UCRT)
Hay un problema conocido en UCRT que se mantiene actualmente por motivos de compatibilidad. Al igual que el S especificador, el Z especificador sin un prefijo modificador de tamaño hace referencia a cuando UNICODE_STRING se usa una función de impresión estrecha (como printf) y cuando ANSI_STRING se usa una función de impresión amplia (como wprintf).
En lugar de Z, use hZ para especificar .ANSI_STRING wZ (o lZ) todavía se puede usar para especificar un UNICODE_STRING.

Normalmente, el carácter de tipo Z tan solo se usa en funciones de depuración de controladores que utilizan una especificación de conversión, como dbgPrint y kdPrint.

En Visual Studio 2015 y versiones posteriores, si el argumento que corresponde a un especificador de conversión de punto flotante (a, A, , e, FfE, , g, ) Ges infinito, indefinido o NaN, el resultado con formato se ajusta al estándar C99. Esta tabla enumera la salida con formato:

Value Output
Infinito inf
NaN reservado nan
NaN de señalización nan(snan)
NaN indefinido nan(ind)

Cualquiera de estas cadenas puede tener como prefijo un signo. Si un carácter especificador de conversión de tipo de punto flotante es una letra mayúscula, la salida también adquiere el formato de letras mayúsculas. Por ejemplo, si el especificador de formato es %F en lugar de %f, se da formato a un infinito como INF en lugar de inf. Las funciones scanf también pueden analizar estas cadenas, por lo que estos valores pueden realizar una acción de ida y vuelta a través de funciones printf y scanf.

Antes de Visual Studio 2015, CRT utilizaba un formato diferente no estándar para la salida de los valores infinito, indefinido y NaN:

Value Output
+ Infinito 1.#INFdígitos aleatorios
-Infinito -1.#INFdígitos aleatorios
Indefinido (igual que un valor NaN simple) dígitos.#INDdígitos aleatorios
NaN dígitos.#NANdígitos aleatorios

Cualquiera de estas cadenas puede haber sido precedida por un signo y se puede haber formateado de forma diferente según el ancho y la precisión del campo, a veces con efectos inusuales. Por ejemplo, printf("%.2f\n", INFINITY) imprimiría 1.#J porque #INF se "redondearía" a una precisión de 2 dígitos.

Nota

Si el argumento correspondiente a %s o %S, o el campo Buffer del argumento que corresponde a %Z, es un puntero nulo, se mostrará "(null)".

Nota

En todos los formatos exponenciales, dos es el número mínimo de dígitos del exponente que debe mostrarse y solo se deben usar tres si es necesario. Con la función _set_output_format, puede establecer el número de dígitos para mostrar en tres para mantener la compatibilidad con el código escrito para Visual Studio 2013 y versiones anteriores.

Importante

Dado que el formato %n es intrínsecamente inseguro, se deshabilita de forma predeterminada. Si %n se encuentra en una cadena de formato, se invoca el controlador de parámetros no válidos, como se describe en Validación de parámetros. Para habilitar la compatibilidad con %n, consulte _set_printf_count_output.

Directivas de marca

El primer campo opcional de una especificación de conversión contiene directivas flag. Este campo contiene cero o más caracteres de marca que especifican la justificación de salida y controlan la salida de signos, espacios en blanco, ceros iniciales, puntos decimales y prefijos octales y hexadecimales. Puede aparecer más de una directiva de marca en una especificación de conversión y los caracteres de marca pueden aparecer en cualquier orden.

Caracteres de marca

Marca Significado Valor predeterminado
- Alinear a la izquierda el resultado dentro del ancho de campo dado. Alinear a la derecha.
+ Usar un signo (+ o -) como prefijo del valor de salida si es de un tipo con signo. El signo solo aparece para valores con signo negativo (-).
0 Si el ancho tiene el prefijo 0, se agregan ceros iniciales hasta que se alcanza el ancho mínimo. Si aparecen tanto 0 como -, 0 se omite. Si se especifica 0 para un formato de entero (i, u, x, X, o, d) y también existe una especificación de precisión( por ejemplo, %04.d), 0 se omite. Si se especifica 0 para el formato de punto flotante a o A, se anteponen ceros iniciales a la mantisa, después del prefijo 0x o 0X. Ningún relleno.
blank (' ') Utilice un espacio en blanco como prefijo del valor de salida si tiene signo y es positivo. El espacio en blanco se omite si aparecen las marcas blank y +. No aparecen espacios en blanco.
# Cuando se usa con el formato o, x o X, la marca # utiliza 0, 0x o 0X, respectivamente, para utilizar como prefijo cualquier valor de salida distinto de cero. No aparece ningún prefijo.
Cuando se usa con el formato e, E, f, F, a o A, la marca # exige al valor de salida que contenga un punto decimal. El punto decimal solo aparece si hay dígitos detrás.
Cuando se usa con el formato g o G, la marca # exige al valor de salida que contenga un punto decimal y evita el truncamiento de los ceros finales.

Se omite cuando se usa con c, d, i, u o s.
El punto decimal solo aparece si hay dígitos detrás. Los ceros finales se truncan.

Especificación del ancho

En una especificación de conversión, el campo de especificación de ancho opcional aparece después de cualquier carácter de marcas . El argumento width es un entero decimal no negativo que controla el número mínimo de caracteres que aparecerán en la salida. Si el número de caracteres en el valor de salida es menor que el ancho especificado, se agregan espacios en blanco a la izquierda o a la derecha de los valores, dependiendo de si se especifica la marca de alineación a la izquierda (-), hasta que se alcanza el ancho mínimo. Si width tiene como prefijo 0, se agregan ceros iniciales a las conversiones de entero y punto flotante hasta que se alcanza el ancho mínimo, excepto cuando la conversión sea a un infinito o NaN.

La especificación de ancho nunca provoca el truncamiento de un valor. Si el número de caracteres del valor de salida es mayor que el ancho especificado, o si el argumento width no se proporciona, todos los caracteres del valor son de salida, de acuerdo con la especificación de precisión.

Si la especificación de ancho es un asterisco (*), un argumento int de la lista de argumentos proporciona el valor. El argumento width debe preceder al valor al que se asigna formato en la lista de argumentos, tal y como se muestra en este ejemplo:

printf("%0*d", 5, 3); /* 00003 is output */

Si el valor de width es pequeño o no está disponible en una especificación de conversión, el valor de salida no se truncará. Si el resultado de una conversión es más ancho que el valor de width, el campo se expande para incluir el resultado de la conversión.

Especificación de la precisión

En una especificación de conversión, el tercer campo opcional es la especificación de precisión. Consta de un punto (.) seguido de un entero decimal no negativo que, según el tipo de conversión, especifica el número de caracteres de cadena, el número de posiciones decimales o el número de dígitos significativos que se van a generar.

A diferencia de la especificación de ancho, la especificación de precisión puede provocar el truncamiento del valor de salida o el redondeo del valor de punto flotante. Si precision se especifica como 0 y el valor que se va a convertir es 0, el resultado es que no hay ninguna salida de caracteres, tal y como se muestra en este ejemplo:

printf( "%.0d", 0 ); /* No characters output */

Si la especificación de la precisión es un asterisco (*), un argumento int de la lista de argumentos proporciona el valor. En la lista de argumentos, el argumento precision debe preceder al valor al que se asigna formato, tal y como se muestra en este ejemplo:

printf( "%.*f", 3, 3.14159265 ); /* 3.142 output */

El carácter type determina la interpretación de precision o la precisión predeterminada cuando precision se omite, tal y como se muestra en la tabla siguiente.

Cómo afectan los valores de precisión al tipo

Tipo Significado Valor predeterminado
a, A La precisión especifica el número de dígitos que se muestran después del punto. La precisión predeterminada es 13. Si la precisión es 0, no se imprime ningún separador decimal a menos que se use la marca #.
c, C La precisión no tiene ningún efecto. El carácter se imprime.
d, i, o, u, x, X La precisión especifica el número mínimo de dígitos que se imprimen. Si el número de dígitos del argumento es menor que precisión, el valor de salida se rellena con ceros a la izquierda. El valor no se trunca cuando el número de dígitos supera al valor de precision. La precisión predeterminada es 1.
e, E La precisión especifica el número de dígitos que se almacenarán después del separador decimal. El último dígito impreso se redondea. La precisión predeterminada es 6. Si precision es 0 o no aparece un número detrás del punto (.), no se imprime el punto decimal.
f, F El valor de precisión especifica el número de dígitos que siguen al separador decimal. Si aparece un separador decimal, aparece al menos un dígito antes. El valor se redondea al número adecuado de dígitos. La precisión predeterminada es 6. Si precision es 0 o no aparece un número detrás del punto (.), no se imprime el punto decimal.
g, G La precisión especifica el número máximo de dígitos significativos que se imprimen. Se imprimen seis dígitos significativos y se truncan los ceros finales.
s, S La precisión especifica el número máximo de caracteres que se imprimen. Los caracteres que rebasen el valor de precision no se imprimen. Los caracteres se imprimen hasta que se encuentra un carácter nulo.

Especificación del tamaño del argumento

En una especificación de conversión, el campo tamaño es un modificador de longitud del argumento del especificador de conversión tipo. Los prefijos del campo tamaño para el campo tipo, que pueden ser hh, h, j, l (L minúscula), L, ll, t, w, z, I (i mayúscula), I32 e I64, especifican el "tamaño" del argumento correspondiente (largo o corto, de 32 o de 64 bits, carácter de un solo byte o carácter ancho) en función del especificador de conversión que modifican. Estos prefijos de tamaño se usan con los caracteres de tipo de los grupos de funciones printf y wprintf para especificar la interpretación del tamaño de los argumentos, como se muestra en la tabla siguiente. El campo tamaño es opcional en algunos tipos de argumento. Cuando no se especifica ningún prefijo de tamaño, el formateador consume argumentos de entero (por ejemplo, char, short, int y long con signo o sin signo, y tipos de enumeración) como tipos int de 32 bits y los argumentos de punto flotante float, double y long double se consumen como tipos double de 64 bits. Este comportamiento coincide con las reglas de promoción de argumentos predeterminadas de las listas de argumentos variables. Para obtener más información acerca de la promoción de argumentos, consulte Puntos suspensivos y argumentos predeterminados en Expresiones postfijas. En los sistemas de 32 y 64 bits, la especificación de conversión de un argumento de entero de 64 bits debe incluir un prefijo de tamaño de ll o I64. De lo contrario, el comportamiento del formateador no queda definido.

Algunos tipos tienen tamaños diferentes en código de 32 bits y de 64 bits. Por ejemplo, size_t es de 32 bits en el código compilado para x86 y de 64 bits en el código compilado para x64. Para crear código de formato independiente de la plataforma para los tipos de ancho variable, puede usar un modificador de tamaño de argumentos de ancho variable. En su lugar, puede usar un modificador de tamaño de argumentos de 64 bits y promover explícitamente el tipo de argumentos de ancho variable a 64 bits. El modificador de tamaño de argumentos I (i mayúscula) específico de Microsoft controla los argumentos de entero de ancho variable, pero se recomiendan los modificadores j, t y z específicos del tipo para la portabilidad.

Prefijos de tamaño para especificadores de tipo de formato printf y wprintf

Para especificar Usar prefijo Con especificador de tipo
char
unsigned char
hh d, i, o, u, x o X
short int
short unsigned int
h d, i, o, u, x o X
__int32
unsigned __int32
I32 d, i, o, u, x o X
__int64
unsigned __int64
I64 d, i, o, u, x o X
intmax_t
uintmax_t
j o I64 d, i, o, u, x o X
long double l (L minúscula) o L a, A, e, E, f, F, g o G
long int
long unsigned int
l (L minúscula) d, i, o, u, x o X
long long int
unsigned long long int
ll (LL minúscula) d, i, o, u, x o X
ptrdiff_t t o I (i mayúscula) d, i, o, u, x o X
size_t z o I (i mayúscula) d, i, o, u, x o X
Carácter de un solo byte h c o C
Carácter ancho l (L minúscula) o w c o C
Cadena de caracteres de un solo byte h s, So Z
Cadena de caracteres anchos l (L minúscula) o w s, So Z

Los tipos ptrdiff_t y size_t son __int32 o unsigned __int32 en plataformas de 32 bits, y __int64 o unsigned __int64 en plataformas de 64 bits. Los prefijos de tamaño I (i mayúscula), j, t y z toman el ancho de argumento correcto para la plataforma.

En Visual C++, aunque long double es un tipo bien diferenciado, tiene la misma representación interna que double.

Un especificador de tipo hc o hC es sinónimo de c en las funciones printf y de C en las funciones wprintf. Un especificador de tipo lc, lC, wc o wC es sinónimo de c en las funciones wprintf y de C en las funciones printf. Un especificador de tipo hs o hS es sinónimo de s en las funciones printf y de S en las funciones wprintf. Un especificador de tipo ls, lS, ws o wS es sinónimo de S en las funciones printf y de s en las funciones wprintf.

Nota

Microsoft-specific:
Los prefijos del modificador de tamaño de argumento I (i mayúscula), I32, I64 y w son extensiones de Microsoft y no son compatibles con ISO C. El prefijo h, cuando se usa con datos de tipo char, y el prefijo l (L minúscula), cuando se usa con datos de tipo double, son extensiones de Microsoft.

Consulte también

printf, _printf_l, wprintf, _wprintf_l
printf_s, _printf_s_l, wprintf_s, _wprintf_s_l
printf_p (Parámetros de posición)