Why does int8_t and user input via cin shows strange result
int8_t
is a typedef for an integer type with the required characteristics: pure 2's-complement representation, no padding bits, size of exactly 8 bits.
For most (perhaps all) compilers, that means it's going to be a typedef for signed char
.(Because of a quirk in the definition of the term signed integer type, it cannot be a typedef for plain char
, even if char
happens to be signed).
The >>
operator treats character types specially. Reading a character reads a single input character, not sequence of characters representing some integer value in decimal. So if the next input character is '0'
, the value read will be the character value '0'
, which is probably 48.
Since a typedef
creates an alias for an existing type, not a new distinct type, there's no way for the >>
operator to know that you want to treat int8_t
as an integer type rather than as a character type.
The problem is that in most implementations there is no 8-bit integer type that's not a character type.
The only workaround is to read into an int
variable and then convert to int8_t
(with range checks if you need them).
Incidentally, int8_t
is a signed type; the corresponding unsigned type is uint8_t
, which has a range of 0..255.
(One more consideration: if CHAR_BIT > 8
, which is permitted by the standard, then neither int8_t
nor uint8_t
will be defined at all.)
Are int8_t and uint8_t intended to be char types?
From § 18.4.1 [cstdint.syn] of the C++0x FDIS (N3290), int8_t
is an optional typedef that is specified as follows:
namespace std {
typedef signed integer type int8_t; // optional
//...
} // namespace std
§ 3.9.1 [basic.fundamental] states:
There are five standard signed integer types: “
signed char
”, “short int
”, “int
”, “long int
”, and “long long int
”. In this list, each type provides at least as much storage as those preceding it in the list. There may also be implementation-defined extended signed integer types. The standard and extended signed integer types are collectively called signed integer types....
Types
bool
,char
,char16_t
,char32_t
,wchar_t
, and the signed and unsigned integer types are collectively called integral types. A synonym for integral type is integer type.
§ 3.9.1 also states:
In any particular implementation, a plain
char
object can take on either the same values as asigned char
or anunsigned char
; which one is implementation-defined.
It is tempting to conclude that int8_t
may be a typedef of char
provided char
objects take on signed values; however, this is not the case as char
is not among the list of signed integer types (standard and possibly extended signed integer types). See also Stephan T. Lavavej's comments on std::make_unsigned
and std::make_signed
.
Therefore, either int8_t
is a typedef of signed char
or it is an extended signed integer type whose objects occupy exactly 8 bits of storage.
To answer your question, though, you should not make assumptions. Because functions of both forms x.operator<<(y)
and operator<<(x,y)
have been defined, § 13.5.3 [over.binary] says that we refer to § 13.3.1.2 [over.match.oper] to determine the interpretation of std::cout << i
. § 13.3.1.2 in turn says that the implementation selects from the set of candidate functions according to § 13.3.2 and § 13.3.3. We then look to § 13.3.3.2 [over.ics.rank] to determine that:
- The
template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, signed char)
template would be called ifint8_t
is an Exact Match forsigned char
(i.e. a typedef ofsigned char
). - Otherwise, the
int8_t
would be promoted toint
and thebasic_ostream<charT,traits>& operator<<(int n)
member function would be called.
In the case of std::cout << u
for u
a uint8_t
object:
- The
template<class traits> basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, unsigned char)
template would be called ifuint8_t
is an Exact Match forunsigned char
. - Otherwise, since
int
can represent alluint8_t
values, theuint8_t
would be promoted toint
and thebasic_ostream<charT,traits>& operator<<(int n)
member function would be called.
If you always want to print a character, the safest and most clear option is:
std::cout << static_cast<signed char>(i);
And if you always want to print a number:
std::cout << static_cast<int>(i);
uint8_t can't be printed with cout
It doesn't really print a blank, but most probably the ASCII character with value 5, which is non-printable (or invisible). There's a number of invisible ASCII character codes, most of them below value 32, which is the blank actually.
You have to convert aa
to unsigned int
to output the numeric value, since ostream& operator<<(ostream&, unsigned char)
tries to output the visible character value.
uint8_t aa=5;
cout << "value is " << unsigned(aa) << endl;
when i try to store a ranged value to a fixed width integer of 8 bit it shows me some other value [ASCII]
Use
std::cout << static_cast<int>( i );
The type std::uint8_t is defined as an alias for unsigned char.
Here is a demonstrative program.
#include <iostream>
#include <cstdint>
int main()
{
std::uint8_t i { 65 };
std::cout << i << '\n';
std::cout << static_cast<int>( i ) << '\n';
}
Its output is
A
65
C++ Even or Odd number program not working properly
You have following code:
int8_t x;
std::cin >> x;
int8_t
is just an alias for char
for your platform and std::istream
when it has type char
as argument inputs one character, not integer. So solution would be to use type int
and you should use it from the beginning as there is no reason at all to use int8_t
in this case.
Related Topics
How to Remove Straight Lines or Non-Curvical Lines in a Canny Image
Why Does Int8_T and User Input via Cin Shows Strange Result
Character Pointers and Integer Pointers (++)
Memory Management Patterns in C++
Why Can't Redefine Type Names in Class in C++
Calling a Random Number Generating Member Function Doesn't Produce Entirely Random Numbers
Delete Calling Destructor But Not Deleting Object
Aligning Static String Literals
How to Convert Platform::String to Char*
How to Compile C++11 Code with Orwell Dev-C++
Qsqldatabase: Qmysql Driver Not Loaded on Ubuntu 15.04 64Bits
How to Allocate a Specific Memory Address Using Pointers in C++
Constraining the Existing Boost.Spirit Real_Parser (With a Policy)
Why Does Msvc Pick a Long Long as the Type for -2147483648
How Does the Main() Method Work in C
C++11: Replace All Non-Owning Raw Pointers with Std::Shared_Ptr()