None
None

Reputation: 2433

Why does std cin work only when used with int variable?

I'm trying to use std::cin after a while.

Using uint8_t or unsigned char:

unsigned char data;
std::cin >> std::dec >> data;

Whatever std::dec is used or not, I get the first ASCII character I type. If I type 12, data is 0x31 not 12. Why can't it parse number until 255 to be stored in a char?

int data;
std::cin >> std::dec >> data;

gives correctly data=12/0xC not 0x31

Using char[N] with std::hex

char data[128];
std::cin >> std::hex >> data;

Also gets the ASCII characters instead of the hexadecimal.

Upvotes: 2

Views: 851

Answers (3)

Hari
Hari

Reputation: 1813

If one wants to see the effect of a manipulator like std::hex while obtaining input with std::cin, one could try with an integer variable as follows,

int test_hex;
std::cin >> std::hex >> test_hex;

If 0x12 is entered as input, the integer value 18 is stored in the integer variable test_hex. We can see that std::hex has had its effect in an input context.

On the other hand, if 0x12 is entered in the following case, the string "0x12" is written into the character array data. Note: the points by Sebastian Redl about the size of the input not exceeding the size of the character array and about rather using std::string should be kept in mind.

char data[128];
std::cin >> std::hex >> data;

Thus, the effect of an I/O manipulator is very much dependent on the type of the variable involved.

Upvotes: 1

goodvibration
goodvibration

Reputation: 6206

In short:

  • cin >> charVar scans a single character from stdin
  • cin >> intVar scans characters from stdin until a non-numeric character is entered

Explaining your observation:

A char variable can store a single ASCII character.

When you type 12, only the character 1 is scanned.

The ASCII code of the character 1 is 0x31.

Upvotes: 6

Sebastian Redl
Sebastian Redl

Reputation: 71989

std::dec and std::hex affect the format of integers.

But as far as the streaming operators are concerned, char and its variants (including uint8_t aren't integers, they're single characters. They will always read a single character, and never parse an integer.

That's just how these functions are defined. There is no way around it. If you want an integer with a limited range, first read into an int (or other integer type that is not a char variant), and then range-check afterwards. You can, if you want, cast it to a small type afterwards, but you probably shouldn't. char types are awkward to work with numerically.

Similarly, reading into an array of char reads a string. (Also, never do that without using setw() to limit the length to fit in the buffer you have. Better yet, use std::string instead.) That's just how it's defined.

Upvotes: 3

Related Questions