Pergunta

No meu programa, eu estatizo os arquivos que eles desejam e enviam os dados. Os campos de uma estatística struct são todos tipos especiais:

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 */
};

O código relevante para minha pergunta segue:

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

Como faço para imprimir esses tipos de maneira portátil e eficiente? No começo, fiz isso sem elencos, adivinhando os especificadores de formato corretos. Além de ser um hábito de programação irritante, isso também significava que meu código não funcionaria em um sistema de 32 bits. Agora, com os elencos, parece funcionar, mas em quantas plataformas?

Foi útil?

Solução

Não há uma maneira totalmente portátil de fazê -lo, e é um incômodo.

C99 fornece um mecanismo para tipos internos como size_t com o %zu notação (e existem alguns qualificadores extras semelhantes).

Também fornece o <inttypes.h> Cabeçalho com macros como o PRIX32 para definir o qualificador correto para imprimir uma constante hexadecimal de 32 bits (neste caso):

printf("32-bit integer: 0x%08" PRIX32 "\n", var_of_type_int32_t);

Para os tipos definidos pelo sistema (como os definidos por Posix), Afaik, não há uma boa maneira de lidar com eles. Então, o que faço é adivinhar uma conversão 'segura' e, em seguida, imprimir de acordo, incluindo o elenco, que é o que você ilustra na pergunta. É frustrante, mas não existe uma maneira melhor que eu conheço. Em caso de dúvida, e usando C99, a conversão para 'Longa Longa' não assinada 'é muito boa; Pode haver um caso para usar um elenco para uintmax_t e prixmax ou equivalente.

Ou, como Fuzxxxl lembrado eu, você pode usar o modificador j para indicar um tipo inteiro 'max'. Por exemplo:

printf("Maximal integer: 0x%08jX\n", (uintmax_t)var_of_type_without_format_letter);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top