What is the correct and portable (Clang / GCC) modifier for uint16_t in sscanf?

I get a warning when I try to compile this code sscanf(value, "%h" PRIu16 "B", &packet_size)  with 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) {
                       ~~~~            ^~~~~~~~~~~~

But if I remove the "h" modifier, I get the following error with 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) {

                                                   ^

What is the correct and portable modifier for uint16_t * in sscanf?

=== Added a more self-evident example below ===

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;
}

Clan Warning

$ 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 Warning

$ 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
   ^
+4
source share
1 answer

As @EOF noted in his comment, fscanfand fprintfeach of them has its own macros.

C99, 7.8.1 4 5 (. 199) , <inttypes.h>

  1. fscanf :

    SCNdN SCNdLEASTN SCNdFASTN SCNdMAX SCNdPTR
    SCNiN SCNiLEASTN SCNiFASTN SCNiMAX SCNiPTR

  2. fscanf :

    SCNoN SCNOLEASTN SCNoFASTN SCNoMAX SCNoPTR
    SCNuN SCNuLEASTN SCNuFASTN SCNuMAX SCNuPTR
    SCNxN SCNxLEASTN SCNxFASTN SCNxMAX SCNxPTR

uint16_t fscanf, 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;
}
+7

Source: https://habr.com/ru/post/1615610/


All Articles