Domanda

Nel mio programma, dichiaro i file desiderati e invio i dati. I campi di una stat struct sono tutti tipi speciali:

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

Segue il codice pertinente per la mia domanda:

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

Come posso stampare questi tipi in modo portatile ed efficiente? All'inizio l'ho fatto senza cast indovinando gli identificatori di formato corretti. Oltre ad essere una fastidiosa abitudine di programmazione, questo significava anche che il mio codice non avrebbe funzionato su un sistema a 32 bit. Ora con i cast sembra funzionare, ma su quante piattaforme?

È stato utile?

Soluzione

Non esiste un modo completamente portatile per farlo ed è un fastidio.

C99 fornisce un meccanismo per tipi incorporati come size_t con la %zu notazione (e ci sono alcuni qualificatori simili extra).

Fornisce inoltre all'intestazione <inttypes.h> macro come PRIX32 per definire il qualificatore corretto per la stampa di una costante esadecimale a 32 bit (in questo caso):

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

Per i tipi definiti dal sistema (come quelli definiti da POSIX), AFAIK, non esiste un buon modo per gestirli. Quindi, quello che faccio è prendere un'ipotesi volante in una conversione "sicura" e quindi stampare di conseguenza, incluso il cast, che è ciò che illustrate nella domanda. È frustrante, ma non c'è modo migliore che io conosca. In caso di dubbio, e usando C99, la conversione in "unsigned long long" è piuttosto buona; potrebbe esserci un caso per usare un cast su uintmax_t e PRIXMAX o equivalente.

Oppure, come FUZxxl ricordato me, puoi usare il modificatore j per indicare un tipo intero 'max'. Ad esempio:

printf("Maximal integer: 0x%08jX\n", (uintmax_t)var_of_type_without_format_letter);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top