什么是sscanf中uint16_t的正确和便携(Clang / GCC)修饰符?

时间:2015-11-12 15:30:56

标签: c++ c gcc clang

当我尝试编译此代码时,我收到一条警告消息 sscanf(value, "%h" PRIu16 "B", &packet_size)  与Clang 600.0.57(OS X)。

warning: format specifies type 'unsigned char *' but the argument has type 'uint16_t *'
      (aka 'unsigned short *') [-Wformat]
    if (sscanf(value, "%h" PRIu16 "B", &packet_size) == 1) {
                       ~~~~            ^~~~~~~~~~~~

但如果我删除修饰符“h”,那么我在GCC 4.8.3(Scientific Linux 7)中会出现以下错误。

warning: format ‘%u’ expects argument of type ‘unsigned int*’, but argument 3 has type ‘uint16_t* {aka short unsigned int*}’ [-Wformat=]
     if (sscanf(value, "%" PRIu16 "B", &packet_size) == 1) {

                                                   ^

sscanf中uint16_t *的正确和便携修饰符是什么?

===在下面添加了更多自我解释示例===

test.c的

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS 1
#endif
#include <inttypes.h>
#include <stdio.h>

int main() {
  char* str = "16 bits";
  uint16_t u16;
  sscanf(str, "%h" PRIu16 " bits", &u16); // Clang warning
  sscanf(str, "%" PRIu16 " bits", &u16); // GCC warning
  sscanf(str, "%" SCNu16 " bits", &u16); // OK for both compilers

  printf("%" PRIu16 " bits\n", u16);

  return 0;
}

Clang警告

$ clang test.c -Wall -Wextra
test.c:10:36: warning: format specifies type 'unsigned char *' but the argument
      has type 'uint16_t *' (aka 'unsigned short *') [-Wformat]
  sscanf(str, "%h" PRIu16 " bits", &u16); // Clang warning
               ~~~~                ^~~~
1 warning generated.

海湾合作委员会警告

$ gcc -Wall -Wextra test.c
test.c: In function ‘main’:
test.c:11:3: warning: format ‘%u’ expects argument of type ‘unsigned int *’, but argument 3 has type ‘uint16_t *’ [-Wformat=]
   sscanf(str, "%" PRIu16 " bits", &u16); // GCC warning
   ^

1 个答案:

答案 0 :(得分:7)

正如@EOF在评论中所说,fscanffprintf每个都有自己的宏。

final C99 draft,§7.8.1第4和第5节(第199页)中,<inttypes.h>应定义以下宏:

  
      
  1. 签名整数的fscanf个宏是:

         

    SCNd N SCNdLEAST N SCNdFAST N SCNdMAX SCNdPTR
      SCNi N SCNiLEAST N SCNiFAST N SCNiMAX SCNiPTR

  2.   
  3. 无符号整数的fscanf宏是:

         

    SCNo N SCNoLEAST N SCNoFAST N SCNoMAX SCNoPTR
      SCNu N SCNuLEAST N SCNuFAST N SCNuMAX SCNuPTR
      SCNx N SCNxLEAST N SCNxFAST N SCNxMAX SCNxPTR

  4.   

如果您想使用uint16_tfscanf视为十进制数字,则必须使用SCNu16

示例:

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>

int main(void) {
    uint16_t input;

    int items = scanf("fetch %" SCNu16 " bits", &input);

    if (items == 1) {
        printf("I'm busy, go fetch those %" PRIu16 " bits yourself.\n", input);
    } else {
        printf("I don't understand what you're saying.\n")
    }

    return 0;
}