Pregunta

En mi programa, establezco los archivos que quieren y les envío los datos.Los campos de una estadística struct 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 forma 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 casts parece funcionar, pero ¿en cuantas plataformas?

¿Fue útil?

Solución

No existe una forma totalmente portátil de hacerlo y es una molestia.

C99 proporciona un mecanismo para tipos integrados como size_t con el %zu notación (y hay algunos calificadores adicionales similares).

También proporciona la <inttypes.h> encabezado 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 existe una buena manera de manejarlos.Entonces, lo que hago es adivinar una conversión "segura" y luego imprimir en consecuencia, incluido el elenco, que es lo que usted ilustra en la pregunta.Es frustrante, pero, que yo sepa, no existe una mejor manera.En caso de duda, y usando C99, la conversión a 'unsigned long long' es bastante buena;podría haber un caso para usar un yeso para uintmax_t y PRIXMAX o equivalente.

O, como FUZxxl recordado yo, puedes usar el modificador j para indicar un tipo de entero 'máximo'.Por ejemplo:

printf("Maximal integer: 0x%08jX\n", (uintmax_t)var_of_type_without_format_letter);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top