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>
32 비트 16 진수 상수를 인쇄하기위한 올바른 예선을 정의하기 위해 Prix32와 같은 매크로가있는 헤더 (이 경우) :
printf("32-bit integer: 0x%08" PRIX32 "\n", var_of_type_int32_t);
시스템 정의 유형 (예 : POSIX로 정의 된 유형)의 경우 AFAIK의 경우 처리 할 수있는 좋은 방법이 없습니다. 그래서, 내가하는 일은 '안전한'변환을 비행 한 다음, 질문에서 설명하는 캐스트를 포함하여 그에 따라 인쇄하는 것입니다. 실망 스럽지만 내가 아는 더 좋은 방법은 없습니다. 의심의 여지가 있고 C99를 사용하는 경우, '서명되지 않은 장거리'로의 전환은 꽤 좋습니다. 캐스트를 사용할 경우가있을 수 있습니다. uintmax_t
및 prixmax 또는 동등한.
또는, AS fuzxxl 상기시킨다 나, 당신은 수정자를 사용할 수 있습니다 j
'최대'정수 유형을 나타냅니다. 예를 들어:
printf("Maximal integer: 0x%08jX\n", (uintmax_t)var_of_type_without_format_letter);