printfを使用してoff_t、nlink_t、size_tおよびその他の特殊なタイプを表示する方法は?
-
05-07-2019 - |
質問
私のプログラムでは、必要なファイルを統計し、データを送信します。 stat struct
のフィールドはすべて特別なタイプです:
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 */
};
質問に関連するコードは次のとおりです。
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);
これらのタイプをポータブルで効率的な方法で印刷するにはどうすればよいですか?最初は、正しいフォーマット指定子を推測することにより、キャストなしで実行しました。迷惑なプログラミング習慣であるだけでなく、これは私のコードが32ビットシステムで動作しないことを意味します。キャストで動作するようになりましたが、プラットフォームの数はいくつですか?
解決
完全に移植できる方法はありませんが、迷惑です。
C99は、size_t
表記を使用した%zu
などの組み込み型のメカニズムを提供します(さらに、いくつかの追加の類似した修飾子があります)。
また、<inttypes.h>
ヘッダーにPRIX32などのマクロを提供して、32ビットの16進定数を印刷するための正しい修飾子を定義します(この場合):
printf("32-bit integer: 0x%08" PRIX32 "\n", var_of_type_int32_t);
システム定義のタイプ(POSIXで定義されているタイプなど)については、それらを処理する良い方法はありません。だから、私がやることは、「安全な」変換で飛ぶ推測をして、それに応じて、キャストを含めて印刷することです。イライラしますが、私が知っているより良い方法はありません。疑わしい場合、およびC99を使用する場合、「unsigned long long」への変換はかなり良いです。 uintmax_t
およびPRIXMAXまたは同等のものへのキャストを使用する場合があります。
または、 FUZxxl リマインド 「最大」整数型を示す修飾子j
。例:
printf("Maximal integer: 0x%08jX\n", (uintmax_t)var_of_type_without_format_letter);
所属していません StackOverflow