Estoy tratando de imprimir tipos como off_t
y size_t
. ¿Cuál es el marcador de posición correcto para printf()
que sea portátil ?
¿O hay una forma completamente diferente de imprimir esas variables?
c
portability
format-specifiers
Georg Schölly
fuente
fuente
fopen
,fseek
, etc en Mac OS Xoff_t
se utiliza para el desplazamiento.Respuestas:
Puede usar
z
para size_t yt
ptrdiff_t como enPero mi página de manual dice que alguna biblioteca más antigua usaba un carácter diferente
z
y desalienta su uso. Sin embargo, está estandarizado (según el estándar C99). Para aquellosintmax_t
yint8_t
destdint.h
y así sucesivamente, hay macros que puede usar, como dijo otra respuesta:Se enumeran en la página de manual de
inttypes.h
.Personalmente, simplemente emitiría los valores
unsigned long
o melong
gustaría que otra respuesta me recomendara. Si usa C99, puede (y debería, por supuesto) emitirunsigned long long
olong long
usar los formatos%llu
o%lld
respectivamente.fuente
%zd
con asize_t
es un comportamiento indefinido debido a la falta de coincidencia de firma (C99 7.19.6.1 # 9). Debe ser%zu
.%zd
con unsize_t
comportamiento indefinido se obtiene de ese párrafo o de cualquier otro. De hecho, la definición de%z
en # 7 permite explícitamente%d
consize_t
y el tipo con signo correspondiente, y §6.2.5 # 9 permite explícitamente usar valores de tipos sin signo donde se espera el tipo con signo correspondiente, siempre que el valor sea un valor no negativo válido del tipo firmado.Para imprimir
off_t
:Para imprimir
size_t
:Para imprimir
ssize_t
: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 es compatible con 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 garantice que sean tan grandes como estos tipos Por lo tanto, debe hacer algo específico de implementación.
Por ejemplo, si su compilador tiene
long long
y su biblioteca estándar es compatible%lld
, puede esperar con confianza que sirva en lugar deintmax_t
. Pero si no es así, tendrá que recurrir along
, lo que podría fallar en algunas otras implementaciones porque es demasiado pequeño.fuente
ssize_t
tenga el mismo tamañosize_t
, por lo que un código verdaderamente portátil debería convertirlointmax_t
e imprimirlo de la%jd
misma maneraoff_t
.Para Microsoft, la respuesta es diferente. VS2013 es en gran medida compatible con C99 pero "[t] he hh, j, z y t prefijos de longitud no son compatibles". Para size_t ", es decir, __int32 sin signo en plataformas de 32 bits, __int64 sin signo en plataformas de 64 bits", utilice el prefijo I (ojo de mayúscula) con el especificador de tipo o, u, x o X. Consulte la especificación de tamaño VS2013
En cuanto a off_t, se define como largo en VC \ include \ sys \ types.h.
fuente
off_t
es siemprelong
eso lo haría de 32 bits (incluso Windows de 64 bits usa 32 bits paralong
).¿Qué versión de C estás usando?
En C90, la práctica estándar es emitir a largo con o sin signo, 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 lo ayudaría 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é los detalles, pero eso es parte de un archivo de inclusión de formato numérico bastante grande.fuente
Querrá usar las macros de formato de inttypes.h.
Consulte esta pregunta: ¿ Cadena de formato multiplataforma para variables de tipo size_t?
fuente
off_t
tipo es más grande que un puntero en cualquier sistema de 32 bits que admita archivos grandes (que actualmente es la mayoría de los sistemas de 32 bits).En cuanto a
man 3 printf
Linux, OS X y OpenBSD, todos muestran soporte%z
parasize_t
y%t
paraptrdiff_t
(para C99), pero ninguno de ellos mencionaoff_t
. Las sugerencias en la naturaleza generalmente ofrecen la%u
conversión paraoff_t
, que es "lo suficientemente correcta" hasta donde puedo decir (ambasunsigned int
yoff_t
varían de manera idéntica entre los sistemas de 64 bits y 32 bits).fuente
unsigned int
y 64 bitsoff_t
. Por lo tanto, el reparto provocaría la pérdida de datos.Vi esta publicación al menos dos veces, porque la respuesta aceptada es difícil de recordar para mí (rara vez uso
z
oj
marcas y parece que no son independientes de la plataforma ).El estándar nunca dice claramente la longitud exacta de los datos
size_t
, por lo que le sugiero que primero verifique la longitudsize_t
en su plataforma y luego seleccione uno de ellos:Y sugiero usar
stdint
tipos en lugar de tipos de datos sin procesar para la consistencia.fuente
%zu
se puede usar para imprimirsize_t
valores. Definitivamente no se debe recurrir al uso de un especificador de formatouint32_t
/uint64_t
para imprimirsize_t
, ya que no hay garantía de que esos tipos sean compatibles.Según recuerdo, la única forma portátil de hacerlo es lanzar el resultado a "unsigned long int" y usarlo
%lu
.fuente
long long
no existe en el estándar C ++ y, por lo tanto, es inherentemente no portátil.use "% zo" para off_t. (octal) o "% zu" para decimal.
fuente