formato - printf reference c++
¿Cómo usar printf para mostrar off_t, nlink_t, size_t y otros tipos especiales? (1)
No hay una forma completamente portátil de hacerlo, y es una molestia.
C99 proporciona un mecanismo para los tipos incorporados como size_t
con la notación %zu
(y hay algunos calificadores adicionales similares).
También proporciona el <inttypes.h>
con macros como PRIX32 para definir el calificador correcto para imprimir una constante hexadecimal de 32 bits (en este caso):
printf("32-bit integer: 0x%08" PRIX32 "/n", var_of_type_int32_t);
Para los tipos definidos por el sistema (como los definidos por POSIX), AFAIK, no hay una buena manera de manejarlos. Por lo tanto, lo que hago es hacer una estimación rápida de una conversión "segura" y luego imprimir de acuerdo con ello, incluido el modelo, que es lo que se ilustra en la pregunta. Es frustrante, pero no hay mejor manera que yo sepa. En caso de duda, y usando C99, entonces la conversión a ''unsigned long long'' es bastante buena; podría haber un caso para usar un cast para uintmax_t
y PRIXMAX o equivalente.
O, como me reminded FUZxxl , puede usar el modificador j
para indicar un tipo entero ''max''. Por ejemplo:
printf("Maximal integer: 0x%08jX/n", (uintmax_t)var_of_type_without_format_letter);
En mi programa, muestro los archivos que desean y les envio los datos. Los campos de una struct
estadística son todos tipos especiales:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
El código relevante para mi pregunta es el siguiente:
len = snprintf( statbuf, STAT_BUFFER_SIZE,
"%crwxrwxrwx %lu %u %u %lld %s %s/r/n",
S_ISDIR( filestats.st_mode ) ? ''d'' : ''-'',
(unsigned long ) filestats.st_nlink,
filestats.st_uid,
filestats.st_gid,
(unsigned long long ) filestats.st_size,
date,
filename);
¿Cómo imprimo estos tipos de manera portátil y eficiente? Al principio lo hice sin conversiones adivinando los especificadores de formato correctos. Además de ser un hábito de programación molesto, esto también significaba que mi código no funcionaría en un sistema de 32 bits. Ahora con los modelos parece funcionar, pero ¿en cuántas plataformas?