كيفية استخدام printf لعرض OFF_T و NLINK_T و SIZE_T وأنواع خاصة أخرى؟
-
05-07-2019 - |
سؤال
في برنامجي ، أقوم بإحصاء الملفات التي يريدونها وأرسل البيانات. حقول الإحصائيات 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 بت (في هذه الحالة):
printf("32-bit integer: 0x%08" PRIX32 "\n", var_of_type_int32_t);
بالنسبة للأنواع المعرفة بالنظام (مثل تلك المحددة بواسطة POSIX) ، AFAIK ، لا توجد طريقة جيدة للتعامل معها. لذا ، فإن ما أقوم به هو أخذ تخمين في التحويل "الآمن" ثم الطباعة وفقًا لذلك ، بما في ذلك فريق الممثلين ، وهو ما توضحه في السؤال. إنه أمر محبط ، لكن لا توجد طريقة أفضل أعرفها. في حالة الشك ، واستخدام C99 ، فإن التحويل إلى "غير موقّع طويل" جيد جدًا ؛ يمكن أن يكون هناك حالة لاستخدام فريق الممثلين uintmax_t
و prixmax أو ما يعادلها.
أو ، كما Fuzxxl ذكر أنا ، يمكنك استخدام المعدل j
للإشارة إلى نوع عدد صحيح "الحد الأقصى". فمثلا:
printf("Maximal integer: 0x%08jX\n", (uintmax_t)var_of_type_without_format_letter);