如何用printf显示off_t,nlink_t,size_t等特殊类型?

2024-10-28 08:37:00
admin
原创
87
摘要:问题描述:在我的程序中,我统计他们想要的文件并发送数据。统计的字段struct都是特殊类型:struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode num...

问题描述:

在我的程序中,我统计他们想要的文件并发送数据。统计的字段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
",
  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 位系统上运行。现在使用强制转换似乎可以正常工作,但在多少个平台上可以正常工作?


解决方案 1:

没有完全可移植的方法来实现这一点,而且很麻烦。

size_tC99为内置类型提供了一种类似%zu符号的机制(并且还有一些额外的、类似的限定符)。

它还为<inttypes.h>标题提供了诸如 PRIX32 之类的宏,以定义用于打印 32 位十六进制常量的正确限定符(在本例中):

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

对于系统定义的类型(例如 POSIX 定义的类型),据我所知,没有好的方法来处理它们。因此,我所做的就是猜测一个“安全”的转换,然后相应地打印,包括强制转换,这就是您在问题中说明的。这令人沮丧,但据我所知没有更好的方法。如果有疑问,并且使用 C99,那么转换为“unsigned long long”就很好;可能存在使用强制转换为uintmax_tPRIXMAX 或等效的情况。

或者,正如FUZxxl 提醒我的那样,您可以使用修饰符j来指示“最大”整数类型。例如:

printf("Maximal integer: 0x%08jX
", (uintmax_t)var_of_type_without_format_letter);

解决方案 2:

如何用printf显示off_t、、等特殊类型nlink_tsize_t

  1. 当类型具有匹配的打印说明符时,使用该

printf("Size is %zu
", object_with_type_size_t);
  1. 当类型可能缺少匹配的打印说明符,但符号已知,并且不是扩展整数类型时,转换为最宽的整数类型。

#include <inttypes.h>
printf("PID is %jd
", (intmax_t) object_with_type_pid_t);
printf("INO is %ju
", (uintmax_t) object_with_type_ino_t);
  1. 当类型可能缺少匹配的打印说明符、符号未知且不是扩展整数类型时,转换为最宽整数类型。nlink_t符号未指定。uintmax_t用于可移植性。用于intmax_t信息性。或者使用精心设计的代码。

printf("link is %ju
", (uintmax_t) object_with_type_nlink_t);
  1. 当整数类型是扩展整数类型(off_t即扩展有符号整数类型)时,我们的选择会变得更加棘手。我们可以像(u)intmax_t上面那样进行转换,并可能截断该值。我们可以转换为浮点类型,并可能丢失精度。我们可以创建精心设计的代码。

printf("link is %jd
", (intmax_t) object_with_type_off_t );
// or 
printf("link is %.0Lf
", (long double) object_with_type_off_t );
// or 

// off_t is a signed extended integer type
#define OFF_DECIMAL_SIZE ((sizeof(off_t) * CHAR_BIT - 1)*28/93 + 3)
char buf[OFF_DECIMAL_SIZE];
printf("link is %s
", prt_off(buf, object_with_type_off_t));

支持代码

// off_t is a signed extended integer type
#define OFF_DECIMAL_STR_SIZE ((sizeof(off_t) * CHAR_BIT - 1)*28/93 + 3)

char* prt_off(char *dest, off_t off) {
  char buffer[OFF_DECIMAL_STR_SIZE];

  // Start filling from the end
  char *p = &buffer[sizeof buffer - 1];
  *p = '';

  // Work with negative values to well handle the min value
  off_t an = off < 0 ? off : -off;

  do {
    *(--p) = (char) ('0' - an % 10);
    an /= 10;
  } while (an);

  if (off < 0) {
    *(--p) = '-';
  }

  size_t size_used = &buffer[sizeof(buffer)] - p;
  return memcpy(dest, p, size_used);
}
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用