0

using scanf to read a specified width integer.

#include <cstdio>

using namespace std;

int main(){
   __int16_t a;
   __int32_t b;
   scanf("%d %d", &a, &b)
   return 0;
}

there is a compiler warning that format specifier "%d" requires 'int *' arg instead of '__int16_t *' so how to fix it?
BTW C++11 is not permitted!

Ruby Sapphire
  • 325
  • 3
  • 4
  • 9
  • There is no format specifier for `__int24_t` because that is not a standard data type - maybe your compiler has some special extension for that (though it's a pretty odd width for an integer type) – UnholySheep Mar 23 '17 at 08:28
  • Also you should probably prefer using C++11 [fixed-width integer types](http://en.cppreference.com/w/cpp/types/integer) – UnholySheep Mar 23 '17 at 08:29
  • `scanf` supports a limited set of data types. Have a look at `format` parameter description in [this link](http://en.cppreference.com/w/cpp/io/c/fscanf), to familiarize yourself with what is supported. – Algirdas Preidžius Mar 23 '17 at 08:31
  • 1
    in C++ use `std::cin` instead. It's much type-safer – phuclv Mar 23 '17 at 09:00

3 Answers3

2

The standard std::scanf only supports standard types. Unless your standard library documents a format specifier that allows the use of non-standard types, you cannot use it to read into non standard types. If it does, then simply follow their documentation.

You could try to first scan into a standard type, then mask the extra bits (if any), and convert. If the input wouldn't overflow the intended target types, then the masking is superfluous.

long temp_a, temp_b; // could use short or int for temp_a
std::scanf("%ld %ld", &temp_a, &temp_b);
__int16_t a = temp_a & 0xffff;
__int32_t b = temp_b & 0xffffffff;

For completeness, if one can use C++11, they have standard fixed width types:

std::int16_t a;
std::int32_t b;
std::scanf("%" PRId16 "%" PRId32, &a, &b)

Or, if your streaming library has overloads for the non-standard types, use std::cin. That way you can deal with invalid input.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

__int16_t is presumably a (compiler-specific) type that is a 16-bit signed integer. scanf() does not generally support such compiler-specific types (and, if it does, it will require a format specifier that is specific to your compiler and library).

In the following, I assume a compiler that supports __int16_t as a 16-bit signed integral type, and scanf() does not provide any way to read one.

 long int some_int;    //  range at least [-2147483647,2147483647]
 __int16_t a;
 if (scanf("%ld ", &some_int) == 1)
 {
      //   report error if some_int outside range a __int16_t can represent

      a = some_int;
 }
 else
 {
       // an error occurred
 }

I don't use int and the %d format specifier in the above, because the C++ standard only requires an int to be able to represent the range of -32767 to 32767 (albeit permitting a larger range). It is conceivable that int for your compiler can represent the range -32678 to 32767 but that an __int16_t represents the range -32767 to 32768. In such a setting, the above code may not handle input of 32768 correctly if it uses int instead of long int.

Personally, I'd probably try using a C++ istream (e.g. std::cin >> a) instead of C's scanf() because, practically, it is likely it likely to work. The reason is that, if an implementation which supports a type like __int16_t, the effort to have included support in istream for it is less than the effort to support it in scanf().

Peter
  • 35,646
  • 4
  • 32
  • 74
  • I suggest removing the space after `%ld` as it will discard whitespace characters _until the first non-whitespace character_ and that will block the input until additional non-whitespace characters are entered. – Spikatrix Mar 23 '17 at 11:55
-5

Use '%d' for __int16_t. I do not know '__int24_t' exists. More here: How to use int16_t or int32_t with functions like scanf.

Community
  • 1
  • 1
vivekn
  • 35
  • 6
  • 5
    `Use '%d' for __int16_t` This will work if, and only if, `sizeof (int) == 2`, which is rarely the case on modern systems. In addition, this should have been a comment, rather than answer (yes, I know that you don't have enough rep for comments, but that does not mean, that you can post half-baked answers). – Algirdas Preidžius Mar 23 '17 at 08:29
  • 1
    Also OP is getting a warning exactly when using `%d` for `__int16_t` – UnholySheep Mar 23 '17 at 08:33