كيفية استخدام printf لعرض OFF_T و NLINK_T و SIZE_T وأنواع خاصة أخرى؟

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

  •  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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top