Why Does Int8_T and User Input via Cin Shows Strange Result

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 a signed char or an unsigned 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 if int8_t is an Exact Match for signed char (i.e. a typedef of signed char).
  • Otherwise, the int8_t would be promoted to int and the basic_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 if uint8_t is an Exact Match for unsigned char.
  • Otherwise, since int can represent all uint8_t values, the uint8_t would be promoted to int and the basic_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



Leave a reply



Submit