61

If I have an integer variable I can use sscanf as shown below by using the format specifier %d.

sscanf (line, "Value of integer: %d\n", &my_integer);

Where can I find format specifiers for uint8_t, uint16_t, uint32_t and uint64_t?

uint64_t has probably %lu.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
Uthman
  • 9,251
  • 18
  • 74
  • 104
  • Isn't `%lu` for `unsigned long`? That's often 32 bits. – MSalters Aug 09 '11 at 08:10
  • 5
    No problem if you use iostreams instead, which adapt to the type – Sebastian Mach Aug 09 '11 at 08:14
  • 1
    @MSalters: beware that for 64 bits targets, Windows 64 `unsigned long` is 32 bits, whereas all UNIX and Linux 64 bits `unsigned long` are 64 bits. – Didier Trosset Aug 09 '11 at 08:47
  • 3
    @Didier Trosset `unsigned long` is NOT 64 bit on all 64 bit UNIX variants. It's 32 bits on 64 bit solaris using gcc. I once had a painful experience learning that it's 64bits on linux. – camelccc Feb 17 '13 at 16:06
  • @camelccc From what is explained there: http://www.unix.org/version2/whatsnew/lp64_wp.html, 64 bit solaris ought to be an exception to UNIX being LP64. – Didier Trosset Feb 18 '13 at 07:44

7 Answers7

97

They are declared in <inttypes.h> as macros: SCNd8, SCNd16, SCNd32 and SCNd64. Example (for int32_t):

sscanf (line, "Value of integer: %" SCNd32 "\n", &my_integer);

Their format is PRI (for printf)/SCN (for scan) then o, u, x, X d, i for the corresponding specifier then nothing, LEAST, FAST, MAX then the size (obviously there is no size for MAX). Some other examples: PRIo8, PRIuMAX, SCNoFAST16.

Edit: BTW a related question asked why that method was used. You may find the answers interesting.

Community
  • 1
  • 1
AProgrammer
  • 51,233
  • 8
  • 91
  • 143
  • 5
    It should be `SCNu32` for `uint32_t`. `SCNi32` is for `int32_t`. – Sander De Dycker Aug 09 '11 at 08:11
  • 1
    -1: They are not declared there, except as a non-standard extension. – Sebastian Mach Aug 09 '11 at 08:32
  • 1
    @phresnel, a question about int8_t obviously assume either C++0X or an extension importing those from C99 before the standard does so. In the first case, `` is present, in the second one, assuming the import of `` at the same time as `` is a pretty safe bet for the implementation I know. – AProgrammer Aug 09 '11 at 08:39
  • As this is a popular Q & A, suggest a comment about a tangential issue: the certainly problematic trailing `'\n'` in a `scanf()` format. – chux - Reinstate Monica Nov 02 '15 at 19:19
7

As others said, include <stdint.h> header that defines the format macros. In C++, however, define __STDC_FORMAT_MACROS prior to including it. From stdint.h:

/* The ISO C99 standard specifies that these macros must only be
   defined if explicitly requested.  */
#if !defined __cplusplus || defined __STDC_FORMAT_MACROS
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • 4
    And according to C++0X, "The macros defined by are provided unconditionally. In particular, the symbol __STDC_FORMAT_MACROS, mentioned in footnote 182 of the C standard, plays no role in C++." But defining __STDC_FORMAT_MACROS may helps with extensions not updated to follow C++0X. – AProgrammer Aug 09 '11 at 09:03
2

According to 7.19.6 Formatted input/output functions of ISO/IEC 9899:TC2, there are no such format specifiers (so I doubt there any for C++2003). Even though there are some #define-macros available in C99's inttypes.h, cinttypes and inttypes.h are not part of the current standard. Of course, fixed-size integer types are non-standard as well.

Anyways, I seriously recommemend using streams instead:

<any_type> x;
f >> x;

and be done. E.g.:

std::stringstream ss;
uint32_t u;
std::cin >> u;

This has the advantage that one time in the future, changing the type of the variable does not cause a cascade of subtle bugs and undefined behaviour.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
  • Using ">>" appears much slower than fscanf, 2-3 times on VC++ 2010 – sergtk Jul 23 '14 at 11:16
  • 1
    @sergtk: That's a feature. By default, iostreams are synced with C functions. You can disable this and the result will be that iostreams are as least as fast. – Sebastian Mach Jul 24 '14 at 07:51
  • I suppose you mean std::ifstream.sync_with_stdio(false); . This does not improve speed reasonably. Moreover if string is read by << operator, then parsed with sscanf, then speed is almost the same as with fscanf. This means that parsing values is slower with iostream and this is not connected with sync. – sergtk Jul 25 '14 at 15:24
  • @sergtk: Hmm, not in my benchmarks: http://stackoverflow.com/a/9747716/76722 and http://stackoverflow.com/a/9212163/76722. And I am not sure why you want to use `<<`, then `sscanf` as an alternative to `fscanf`. – Sebastian Mach Jul 28 '14 at 10:11
  • First link contains testing when chars are read, this does not involves converting types. Second link is more interesting since it already contains int-s. But we used different compilers. I tested mostly with int-s and float-s. Even more interesting that in fact all file reading in my testing is still with std::ifstream. But initially it was used to read any types with "<<". But optimised version reads strings with getline(ifstream&, string&), then parsed with sscanfs for strings. Performance improved just because using other conversion of types, not by optimising reading data. – sergtk Jul 28 '14 at 12:06
0

The right format to read a uint64_t (typedef unsigned long long int) is, with scanf and not sscanf, "%" SCNu64 and for print is also SCNu64 Example. in your code you read for example my_integer variable, then you do scanf ("Value of integer:%" SCNu64, & my_integer); and to write the same but with printf.

Alejandro Caro
  • 998
  • 1
  • 10
  • 22
0

You can check types in <cstdint> for C++ or in <types.h> for C. Then you can specify format which is currently compiled on your machine. If variable is unsigned then you need to use %u, if variable is signed, then use %d. For variables size lower than 32 bytes you don't have to specify long prefix.

In my configuration I have 64 bit program, so my uint64_t is compiled as unsigned long long int, so it means to use %llu. If your program will be compiled in 32 bit you can use %lu because uint64_t will be compiled as unsigned long int

But who is using x86 still? :), so generally:

uint8_t, uint16_t, uint32_t - %u
uint64_t - %llu
int8_t, int16_t, int32_t - %d
int64_t -%lld
Paweł Iwaneczko
  • 853
  • 1
  • 10
  • 13
0

In C, the header is <inttypes.h>, and formats such as SCNX8, SCNd16.

The same header probably works for C++ too.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    `` has been imported in the C++ standard at the same time as `` (which declares the typedef `int8_t` and friends), formally in C++0X but in practice available as extension in implementations having a strong relationship with an implementation of C99. – AProgrammer Aug 09 '11 at 08:24
-2

Refer to this for sscanf usage.

These datatypes are defined in stdint.h. Refer here for stdint.h

Shash

Shash316
  • 2,218
  • 18
  • 19
  • Refering is not answering. It primarily tells you don't know yourself. – Sebastian Mach Aug 09 '11 at 08:20
  • I dont believe in copy, paste if it is available over net!! + This is like joining the dots, sscanf & stdint, dont you think ? – Shash316 Aug 09 '11 at 08:49
  • 2
    But stackoverflow answers should stay valid in itself. At least tell where at http://www.cplusplus.com/reference/clibrary/cstdio/sscanf/ it is mentioned how to format int64 et al. – Sebastian Mach Aug 09 '11 at 08:57