Wie verwendet ich printf zum Anzeigen von OFF_T, NLINK_T, Size_T und anderen speziellen Typen?

StackOverflow https://stackoverflow.com/questions/1401526

  •  05-07-2019
  •  | 
  •  

Frage

In meinem Programm stehe ich die gewünschten Dateien und sende die Daten. Die Felder eines Status struct sind alle besonderen Typen:

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

Der entsprechende Code für meine Frage folgt:

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

Wie drucke ich diese Typen tragbar und effizient aus? Zuerst habe ich es ohne Abgüsse gemacht, indem ich die korrekten Format -Anträge erraten habe. Abgesehen davon, dass es sich um eine nervige Programmiergewohnheit handelte, bedeutete dies auch, dass mein Code nicht auf einem 32 -Bit -System funktioniert. Jetzt mit den Casts scheint es zu funktionieren, aber auf wie vielen Plattformen?

War es hilfreich?

Lösung

Es gibt keine voll tragbare Möglichkeit, es zu tun, und es ist ein Ärgernis.

C99 bietet einen Mechanismus für eingebaute Typen wie size_t mit dem %zu Notation (und es gibt einige zusätzliche, ähnliche Qualifikation).

Es liefert auch die <inttypes.h> Header mit Makros wie Prix32, um das richtige Qualifikationsmerkmal zum Drucken einer 32-Bit-Hexadezimalkonstante (in diesem Fall) zu definieren:

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

Für die systemdefinierten Typen (z. Ich mache also eine fliegende Vermutung bei einer "sicheren" Konvertierung und drucke dann entsprechend, einschließlich der Besetzung, was Sie in der Frage veranschaulichen. Es ist frustrierend, aber es gibt keinen besseren Weg, den ich kenne. Im Zweifelsfall und die Verwendung von C99 ist die Konvertierung in "Unsigned Long" ziemlich gut; Es könnte einen Fall für die Verwendung einer Besetzung zu geben uintmax_t und Prixmax oder gleichwertig.

Oder, as Fuzxxl erinnerte Ich kann den Modifikator verwenden j um einen 'max' Ganzzahltyp anzuzeigen. Zum Beispiel:

printf("Maximal integer: 0x%08jX\n", (uintmax_t)var_of_type_without_format_letter);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top