formato - scanf c
¿Cómo debo imprimir tipos como off_t y size_t? (10)
¿Qué versión de C estás usando?
En C90, la práctica estándar es lanzar a largo firmado o sin firmar, según corresponda, e imprimir en consecuencia. He visto% z para size_t, pero Harbison y Steele no lo mencionan en printf (), y en cualquier caso eso no te ayuda con ptrdiff_t o lo que sea.
En C99, los diversos tipos _t vienen con sus propias macros printf, por lo que algo como "Size is " FOO " bytes."
No sé detalles, pero eso es parte de un formato numérico bastante grande, incluido el archivo.
Estoy intentando imprimir tipos como off_t
y size_t
. ¿Cuál es el marcador de posición correcto para printf()
que es portátil ?
¿O hay una forma completamente diferente de imprimir esas variables?
Mirando man 3 printf
en Linux, OS X y OpenBSD todos muestran soporte para %z
para size_t
y %t
para ptrdiff_t
(para C99), pero ninguno de ellos menciona off_t
. Las sugerencias en la naturaleza suelen ofrecer la conversión de %u
para off_t
, que es "lo suficientemente correcta" por lo que puedo decir (tanto unsigned int
como off_t
varían de forma idéntica entre los sistemas de 64 bits y 32 bits).
Para Microsoft, la respuesta es diferente. VS2013 es en gran medida compatible con C99, pero "[t] e los prefijos de longitud hh, j, zyt no son compatibles." Para size_t ", es decir, sin firmar __int32 en plataformas de 32 bits, sin firmar __int64 en plataformas de 64 bits" use el prefijo I (ojo de capital) con el tipo especificador o, u, x o X. Consulte la especificación de tamaño de VS2013
En cuanto a off_t, se define como long en VC / include / sys / types.h.
Para imprimir off_t
:
printf("%jd/n", (intmax_t)x);
Para imprimir size_t
:
printf("%zu/n", x);
Para imprimir ssize_t
:
printf("%zd/n", x);
Consulte 7.19.6.1/7 en el estándar C99, o la documentación POSIX más conveniente de los códigos de formato:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Si su implementación no admite esos códigos de formato (por ejemplo, porque está en C89), entonces tiene un pequeño problema ya que AFAIK no hay tipos enteros en C89 que tengan códigos de formato y se garantiza que sean tan grandes. como estos tipos. Por lo tanto, debe hacer algo específico de la implementación.
Por ejemplo, si su compilador tiene una long long
y su biblioteca estándar admite %lld
, puede esperar con confianza que se intmax_t
en lugar de intmax_t
. Pero si no lo hace, tendrá que recurrir a long
, que fallaría en algunas otras implementaciones porque es demasiado pequeño.
Por favor use% lu. Off_t no tiene firma de largo.
Puedes usar z
para size_t t
para ptrdiff_t como en
printf("%zu %zd", size, ptrdiff);
Pero mi página de manual dice que alguna biblioteca anterior usaba un carácter diferente de z
y desalienta su uso. Sin embargo, está estandarizado (según el estándar C99). Para aquellos intmax_t
e int8_t
de stdint.h
y más, hay macros que puede usar, como otra respuesta dijo:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
Se enumeran en la página de inttypes.h
de inttypes.h
.
Personalmente, simplemente lanzaría los valores a unsigned long
o long
como recomienda otra respuesta. Si usas C99, entonces puedes (y deberías, por supuesto) convertir a unsigned long long
o long long
y usar los %llu
o %lld
, respectivamente.
Querrá utilizar las macros de formateo de inttypes.h.
Consulte esta pregunta: cadena de formato de plataforma cruzada para variables de tipo size_t?
Según recuerdo, la única forma portátil de hacerlo es convertir el resultado en "unsigned long int" y usar %lu
.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
Vi esta publicación al menos dos veces, porque la respuesta aceptada es difícil de recordar para mí (rara vez uso z
o j
flags y no parecen independientes de la plataforma ).
El standard nunca dice claramente la longitud de datos exacta de size_t
, por lo que le sugiero que primero verifique la longitud size_t
en su plataforma y luego seleccione una de ellas:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
Y sugiero usar tipos de stdint
lugar de tipos de datos sin procesar para la consistencia.
usa "% zo" para off_t. (octal) o "% zu" para decimal.