C 语言中数据类型 BYTE、WORD 和 DWORD 的格式说明符?

问题描述 投票:0回答:2

在 C 语言中,与 printf 和 scanf 函数一起使用的数据类型 BYTE、WORD 和 DWORD 最合适的格式说明符是什么? 我很难通过控制台显示 BPB 字段的值。

例如,如果我尝试使用“%lu”显示 BPB_BytsPerSec,我会得到不寻常的数字..

printf("Bytes per Sector: %lu", b->BPB_BytsPerSec);

我得到的值是“514”,我认为这是错误的解释。请建议出路。谢谢。

(我在 64 位 Windows 上通过 MinGW 使用 gcc 5.1)

这是我们正在讨论的结构:

/* BPB Structure Collected from internet */
struct BPB_FAT32 {
  BYTE  BS_jmpBoot[3];      // 0  
  BYTE  BS_OEMName[8];      // 3  
  WORD  BPB_BytsPerSec;     // 11 
  BYTE  BPB_SecPerClus;     // 13 
  WORD  BPB_ResvdSecCnt;    // 14 
  BYTE  BPB_NumFATs;        // 16 
  WORD  BPB_RootEntCnt;     // 17 
  WORD  BPB_TotSec16;       // 19 
  BYTE  BPB_Media;          // 21
  WORD  BPB_FATSz16;        // 22
  WORD  BPB_SecPerTrk;      // 24
  WORD  BPB_NumHeads;       // 26
  DWORD BPB_HiddSec;        // 28
  DWORD BPB_TotSec32;       // 32
  DWORD BPB_FATSz32;        // 36
  WORD  BPB_ExtFlags;       // 40
  WORD  BPB_FSVer;          // 42
  DWORD BPB_RootClus;       // 44
  WORD  BPB_FSInfo;         // 48
  WORD  BPB_BkBootSec;      // 50
  BYTE  BPB_Reserved[12];   // 52
  BYTE BS_DrvNum;           // 64
  BYTE BS_Reserved1;        // 65
  BYTE BS_BootSig;          // 66
  DWORD BS_VolID;           // 67
  BYTE BS_VolLab[11];       // 71
  BYTE BS_FilSysType[8];    // 82
};

这是我试图显示这些值的函数..

void DisplayBlock(struct BPB_FAT32* b){

    printf("\n\n\t1.  Jump to boot code..........: 0x%02x%02x%02x",b->BS_jmpBoot[0],b->BS_jmpBoot[1],b->BS_jmpBoot[2]);
    printf("\n\n\t2.  OEM name & version.........: "); for(int i=0; i<8;i++) printf("%c",(char)b->BS_OEMName[i]);
    printf("\n\n\t3.  Bytes per Sector...........: %u",b->BPB_BytsPerSec);      // WORD
    printf("\n\n\t4.  Sectors per Cluster........: %lu", b->BPB_SecPerClus);    // BYTE
    printf("\n\n\t5.  Reserved Sectors Count.....: %lu", b->BPB_ResvdSecCnt);   // WORD
    printf("\n\n\t6.  Number of FAT32 tables.....: %u", b->BPB_NumFATs);        // BYTE
    printf("\n\n\t7.  Number of Root Entries.....: %lu", b->BPB_RootEntCnt);    // WORD
    printf("\n\n\t8.  Total Sectors 16bits.......: %lu",b->BPB_TotSec16);       // WORD
    printf("\n\n\t9.  Media Descriptor...........: %lu",b->BPB_Media);          // BYTE   0xF8 is the standard value for fixed media
    printf("\n\n\t10. Size According to FAT16....: %lu",b->BPB_FATSz16);        // WORD
    printf("\n\n\t11. Number of Sector per Track.: %lu",b->BPB_SecPerTrk);      // WORD
    printf("\n\n\t12. Number of Heads............: %lu",b->BPB_NumHeads);       // WORD
    printf("\n\n\t13. Number of Hidden Sectors...: %lu", b->BPB_HiddSec);       // DWORD
    printf("\n\n\t14. Total Sectors 32bits.......: %lu", b->BPB_TotSec32);      // DWORD
    /* FAT32 Specific Fields Starting offset:36 */
    printf("\n\n\t15. Size According to FAT32....: %lu", b->BPB_FATSz32);       // DWORD
    //printf("\n\n\t16. Extended Flags............: %u",b->BPB_ExtFlags);       // WORD  Usually 0.
    printf("\n\n\t17. File System Version........: %lu", b->BPB_FSVer);         // WORD         Must be 0:0
    printf("\n\n\t18. Root Cluster Number........: %lu",b->BPB_RootClus);       // DWORD        Usually 2
    printf("\n\n\t19. File System Information....: %lu",b->BPB_FSInfo);         // WORD
    printf("\n\n\t20. Backup Boot Sector.........: %lu",b->BPB_BkBootSec);      // WORD         Recomended 6
    //  BYTE  BPB_Reserved[12]  
    /* Remaining common fields FAT12/FAT16 BPB*/
    printf("\n\n\t21. Drive Number...............: %u",b->BS_DrvNum);           // BYTE
    //  BYTE BS_Reserved1;      /* 65 reserved          */
    printf("\n\n\t22. Boot Signature.............: %u",b->BS_BootSig);          // BYTE
    printf("\n\n\t23. Volume ID..................: %lu",b->BS_VolID);           // DWORD
    printf("\n\n\t24. Volume Lable...............: %s",b->BS_VolLab); //for(int i=0;i<11;i++) printf("%c",b->BS_VolLab[i]);     // BYTE [11]
    printf("\n\n\t25. File System Type...........: "); for(int i=0;i<8;i++) printf("%c",b->BS_FilSysType[i]);  // BYTE [8]
}

这是令人不满意的输出:

c filesystems format-specifiers fat32 fat
2个回答
2
投票
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned long long QWORD;

0
投票

让我们制作一些足够可移植的东西,当发现它被用在假设不再成立的地方时,它会给我们一个编译器警告。

首先,我们需要看看这些类型是如何定义的。在我的 64 位机器上

// C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared\minwindef.h

typedef unsigned long       DWORD;
typedef unsigned char       BYTE;
typedef unsigned short      WORD;

现在32位的情况如何?

根据此链接的 MSDN 页面,定义仍然相同,因此大小的差异来自于

long
等在 32 位 Windows 上具有不同大小的事实,而不是来自 DWORD 等的任何不同定义。他们自己。 https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types

因此,问题是,我们如何便携地打印

unsigned long
等? C99 给了我们几个答案。

PRI 宏

首先,

中定义了
PRIxxx宏。 https://en.cppreference.com/w/c/types/integer

长度修饰符

C99 中的

printf
添加了有趣的长度修饰符。 https://en.cppreference.com/w/c/99

它们可以在 Visual Studio 中使用,假设您有足够新的版本。 https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specation-syntax-printf-and-wprintf-functions?view=msvc-170

  • z
    size_t
    及其签名版本
  • 的长度修饰符
  • t
    ptrdiff_t
    及其无符号版本
  • 的长度修饰符
  • j
    intmax_t
    uintmax_t
  • 的长度修饰符

对于

WORD
,即
unsigned short
,修饰符是
h
,所以使用
%hu
https://en.cppreference.com/w/c/io/fprintf

printf("\n\n\t3.  Bytes per Sector...........: %hu",b->BPB_BytsPerSec);      // WORD

依靠隐性促销

当小于 int 的整数类型作为参数传递给可变参数函数(printf 就是)时,它会被提升为 int 或 unsigned int。所以,你可以像打印一个 int 一样打印一个 WORD。 https://en.cppreference.com/w/c/language/conversion

投射到
intmax

投射到

intmax_t
uintmax_t
,然后分别使用
%jd
%ju
。这每次都会有效,因为
intmax
是系统上最大的可能类型。 https://stackoverflow.com/a/3171743/1047788

printf("\n\n\t13. Number of Hidden Sectors...: %ju", (uintmax_t)b->BPB_HiddSec);       // DWORD
© www.soinside.com 2019 - 2024. All rights reserved.