Wie verwendet ich printf zum Anzeigen von OFF_T, NLINK_T, Size_T und anderen speziellen Typen?
-
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?
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);