¿Cómo debo imprimir tipos como off t y size t?


Estoy tratando de imprimir tipos como off_t y size_t. ¿Cuál es el marcador de posición correcto para printf() eso es portable?

¿O hay una forma completamente diferente de imprimir esas variables?

Author: hippietrail, 2009-02-25

10 answers

Puedes usar z para size_t y t para ptrdiff_t como en

printf("%zu %zd", size, ptrdiff);

Pero mi página de manual dice que alguna biblioteca antigua usaba un carácter diferente a z y desaconseja su uso. Sin embargo, está estandarizado (por el estándar C99). Para esos intmax_t y int8_t de stdint.h y así sucesivamente, hay macros que puede usar, como otra respuesta dijo:

printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);

Están listados en la página de manual de inttypes.h.

Personalmente, yo simplemente lanzaría los valores a unsigned long o long como otro la respuesta recomienda. Si usa C99, entonces puede (y debe, por supuesto) convertir a unsigned long long o long long y usar los formatos %llu o %lld respectivamente.

 93
Author: Johannes Schaub - litb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-06 17:46:36

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);

Ver 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 tienen códigos de formato y están garantizados para ser tan grande como estos tipos. Así que necesitas hacer algo específico para la implementación.

Por ejemplo, si su compilador tiene long long y su biblioteca estándar admite %lld, puede esperar con confianza que sirva 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.

 88
Author: Steve Jessop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-09 21:35:47

Para Microsoft, la respuesta es diferente. VS2013 es en gran medida compatible con C99, pero " los prefijos de longitud hh, j, z y t no son compatibles."Para size_t "es decir, unsigned __int32 en plataformas de 32 bits, unsigned __int64 en plataformas de 64 bits" use el prefijo I (ojo de capital) 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 long en VC\include\sys\types.h.

 5
Author: NoBrassRing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-20 15:39:47

¿Qué versión de C está utilizando?

En C90, la práctica estándar es convertir 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 bajo printf (), y en cualquier caso eso no te 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 conozco los detalles, pero eso es parte de un formato numérico bastante grande que incluye file.

 3
Author: David Thornley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-25 17:20:32

Querrá usar las macros de formato de inttypes.h.

Vea esta pregunta: Cadena de formato multiplataforma para variables de tipo size_t?

 3
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:24

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 generalmente ofrecen la conversión %u para off_t, que es "lo suficientemente correcta" por lo que puedo decir (tanto unsigned int como off_t varían idénticamente entre sistemas de 64 y 32 bits).

 1
Author: dwc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-25 17:37:30

Vi este post al menos dos veces, porque la respuesta aceptada es difícil de recordar para mí(rara vez uso z o jbanderas y parecen no plataforma independiente).

El estándar nunca dice claramente la longitud exacta de los datos de size_t, por lo que sugiero que primero verifique la longitud size_t en su plataforma y luego seleccione uno de ellos:

if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64

Y sugiero usar tipos stdint en lugar de tipos de datos sin procesar para la consistencia.

 -2
Author: elinx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:51

Según recuerdo, la única forma portátil de hacerlo, es lanzar el resultado a "unsigned long int" y usar %lu.

printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
 -3
Author: James Curran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-26 04:34:13

Utilice %lu. Off_t es unsigned long.

 -5
Author: Manoj Rana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-28 11:32:40

Use" % zo " para off_t. (octal) o" % zu " para decimal.

 -8
Author: Shankar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-26 12:12:52