3
char input1;
std::cout << "input1 : ";
std::cin >> input1;

int input2;
std::cout << "input2 : ";
std::cin >> input2;

std::cout << input1 << std::endl;
std::cout << input2 << std::endl;

return 0;

I wrote 'a' at input1 and 'a' at input2.

Ouput is like this.
input1 : a
input2 : a
a
-858993460

I'm curious...'a' charter is 97 in dec. why does it print -858993460? 'a' is not converted to 97 automatically? why?

Coding Mash
  • 3,338
  • 5
  • 24
  • 45
user1705636
  • 233
  • 1
  • 6
  • 14
  • 1
    @LuchianGrigore I assume OP means the character literal `'a'`, using ASCII. –  Nov 13 '12 at 14:24
  • check this answer: http://stackoverflow.com/a/2410227/516486 – Robertas Nov 13 '12 at 14:25
  • 10
    There's a very simple rule you need to follow when using streams: ___Always check whether input succeeded___ before you use the values. You failed that, hence the funny results. – sbi Nov 13 '12 at 14:34

5 Answers5

18

a, as a string, is not convertible to an int by the rules std::cin follows. Consider this: a is not a valid integer in base 10. std::cin will fail to convert the string "a" to an int.

The reason it prints -858993460 is because the int is not initialized, so it could print anything, or nothing, or do whatever it desires (look up undefined behaviour).

Try something like this instead:

char input2_chr;
std::cin >> input2_chr;
int input2 = input2_chr;
  • 4
    Also, `-858993460` is simply `0xCCCCCCCC` which is the value your debugger assigned to an uninitialized int. Try using a release build and you will see that the value will change (the variable won't be initialize and contain whatever was at that memory location before). – emartel Nov 13 '12 at 14:28
  • @Default it is *undefined behavior*, so it could do anything. It is not specified what will happen. See [this answer about UB](http://stackoverflow.com/questions/1553382/is-delete-equal-to-delete/1553407#1553407). –  Nov 13 '12 at 14:30
  • @Let_Me_Be could you elaborate? –  Nov 13 '12 at 14:32
  • 2
    @sbi I'm a dude. That would be some seriously undefined behaviour – default Nov 13 '12 at 14:33
  • @Aardvark Exceptions are meant to be used for exceptional cases, not to represent normal flow of the code. C++ isn't Java. – Šimon Tóth Nov 13 '12 at 14:34
  • 1
    @Let_Me_Be and why is failing to parsing an int not an exceptional case? What would you return from a function `int parse_int(string)` if the conversion fails? –  Nov 13 '12 at 14:36
  • 1
    @Let_Me_Be Ahaha, are you seriously saying error codes are better than exceptions. Or even better, fail states. – Cat Plus Plus Nov 13 '12 at 14:36
  • 1
    @Default: The C++ standard couldn't care less. In fact, whether you are still male is undefined after you invoked UB. An implementation that changed (or removed, FTM) your sex arbitrarily would be standard-conforming. – sbi Nov 13 '12 at 14:36
  • It's easy to actually throw if you feel you should: `if (!(cin >> input2)) throw ThisWasNotAnIntegerExceptionLOLJAVA();` :) – jrok Nov 13 '12 at 14:37
  • 4
    @jrok You can simply enable exceptions instead. – R. Martinho Fernandes Nov 13 '12 at 14:38
  • @Aardvark These aren't error states. Each file has EOF, getting something else on interactive input than what you expect is also normal. – Šimon Tóth Nov 13 '12 at 14:39
  • @R.MartinhoFernandes Yes, true. Aardwark, see http://www.cplusplus.com/reference/iostream/ios/exceptions/ – jrok Nov 13 '12 at 14:39
  • He knows about that, and don't ever link to cplusplus.com – Cat Plus Plus Nov 13 '12 at 14:40
  • @jrok as my answer says, exceptions are not *enabled by default*. –  Nov 13 '12 at 14:40
  • IO Streams in C++ have their basic design dating back to before exceptions were added to the language. I fail to see how not using something which didn't exist at the time is a sign of terrible design. Or is it the fact that backward compatibility was paid attention all along which is the terrible design? – AProgrammer Nov 13 '12 at 14:41
  • 1
    No, the problem is that their fundamental design is horrific. – Puppy Nov 13 '12 at 14:51
  • The default is set to not throw because streams are usually used interactively where the error can be immediately detected and thus allow the programer to re-request input (fix the problem at the point of error). Exceptions on the other hand are used where error can be detected but not fixed locally (because you don't have the context) thus you need to throw an exception up the call chain to a point where enough context is retained to fix the problem. With interactive input the context is already there so setting an error state is the correct design. – Martin York Nov 13 '12 at 14:59
  • You mean that you want to have to wrap all IO in a try...catch block, rather than just using an `if`. You can set any given stream to throw on any given error bit, but no one does, because it's not what you would ever want. – James Kanze Nov 13 '12 at 15:12
  • 1
    @LokiAstari I disagree that streams are usually used interactively (but then, most of my work has been on servers, where the code runs as a demon with no terminal attached). But _nothing_ that you get on input can really be considered exceptional, and input errors generally have to be handled immediately, not several layers up the call stack. – James Kanze Nov 13 '12 at 15:15
  • @JamesKanze: Rephrasing. Most work with streams that contains errors is done with users interactively. Work done with pre-formatted files (or files with a specific format) are unlikely to have errors. In the first case errors can be fixed interactively thus error codes are good. In the second case errors can not be fixed and thus exceptions are probably better. So for me on the server end exceptions would be a better solution (as you can't fix the problem) so should be handled higher up the call stack (sending an e-mail to admin that the processes failed). But this is very general discussion. – Martin York Nov 13 '12 at 15:36
  • @JamesKanze: Now there are cases were errors in pre-formated files are the norm (HTML springs to mind). In this case fixing at the point of the problem with simple heuristics is usually the best choice and only generating exceptions if the heuristics fail. – Martin York Nov 13 '12 at 15:38
  • 1
    @LokiAstari In my experience, work with files is just as likely to cause errors as interactive input. After all, who wrote the files? (Input to the C++ compiler is a file. You certainly wouldn't claim that errors in a C++ program are an "exceptional case".) – James Kanze Nov 13 '12 at 16:29
  • @AProgrammer: Many designs that date back far into the past are considered bad now. I claim the IO streams design is bad, and what I list ___[here](http://chat.stackoverflow.com/rooms/10/conversation/sbis-gripes-with-iostreams)___ is just the start. They are ~30 years old, and are a prime example of the _C With Classes_ era that for good reason we now look down our noses at. – sbi Nov 13 '12 at 16:38
  • @JamesKanze: Your C++ case is like the HTML example (and closer aligned to user input than processing on a server). So there are exceptions to the rule. But in my experience input files (for server processing) are generally machine generated. In this case bad input is exceptional. Fixing the error on the fly is imposable (as it means there is a bug in either current or the generating program) and thus an exception is more appropriate. I would consider C++ files the same as user input (its just buffered slightly). – Martin York Nov 13 '12 at 16:42
  • @LokiAstari In the case of machine generated files (and especially binary files), an exception may be warrented. But my experience has been that even on servers, most input is written by human beings. I guess it depends on what the server is doing. (On a lot of servers, about the only "files" that it will read are configuration files. On the other hand, client input is often processed as if it were a file.) – James Kanze Nov 13 '12 at 18:40
  • @JamesKanze: If your configuration file is bad there is no way to fix that (exception). User files on servers..... mmm maybe webservers. I'll put money that most servers running non interactively are processing machine generated files. Banking/Weather Modelling/Logistics/Large computational tasks/Payroll etc. – Martin York Nov 13 '12 at 18:59
  • @sbi, my definition of bad design is "didn't solve correctly the problem it had to solve with the constraints and knowledge of the time it was made", yours seems to be "doesn't solve correctly today's problems with the constraints -- excluded the one of compatibility -- and knowledge -- included the insight allowed by the experience acquired with that design -- of today". I don't judge the quality of a design without taking into account the context in which it was made and evolved, it's sure to be unfair. Well I'm ranting against programmers' excessively harsh judgements, a lost cause. – AProgrammer Nov 13 '12 at 19:57
  • @sbi, BTW, I wanted to add that the fact that a design was sound for its time and purpose doesn't mean it is adequate for our time and purpose, but the basic IOStream design, easy chained calls, separation of concerns between a formatting class (iostream) and an IO class (streambuf), possibility to integrate easily formatting of user provided types, is still sound and very modern if you compare to what was available at the time (most languages had ad hoc special instructions). Details can be improved, and, if you consider locale as a part of IOStream, locale usage is at best too complex. – AProgrammer Nov 13 '12 at 20:13
  • @AProgrammer: I don't condemn those who designed the streams. Nevertheless, given today's standards, they *are* bad, even though they *were* not back then. Jerry Schwarz (or whoever) might have done a fantastic job back then, but this is 30 years later and requirements have changed. – sbi Nov 13 '12 at 20:26
  • @LokiAstari If your configuration file is bad, you still want to continue reading it, in order to output all of the errors. (But I think we agree on the fundamental issue: if the file is machine generated, you have a right to expect it to be correct, and an exception is in order; if a human had something to do with it, on the other hand, you really have to expect it to have syntax errors, and you want to process the error immediately.) – James Kanze Nov 14 '12 at 09:39
  • @sbi There are some small issues with iostream (the names of the public functions of `streambuf`, for example), but on the whole, even by today's standard, it is far better designed than the IO for almost any other language. If you want exceptions, you can have them; most people don't, because they are usually the wrong way of handling errors in input. As for the rest, iostream is really a model of how to handle customization in C++, for the reasons AProgrammer has pointed out. – James Kanze Nov 14 '12 at 09:43
  • I gave my list, @James, you dismissed one item as minor, and skipped over all the others. I don't see anything I could reply to turn this into a discussion. – sbi Nov 14 '12 at 13:29
  • @sbi I can't access your list (the spam filters where I work won't let me), so I can't comment on it. But globally, compared to the IO systems I've seen in other languages, Schwarz's original iostream was, and still is, a model of good design. (The committee didn't help it by templating it, but it's still better than what's available in other langauges.) – James Kanze Nov 14 '12 at 14:28
  • @James: Since cannot access my arguments, but repeated yours instead, I don't see how this could turn into a discussion. So I am bowing out here. – sbi Nov 14 '12 at 14:37
6

I think the input simply failed, and the value you're seeing is the result of undefined behavior (input2 was never written to).

If you try to read an integer, the character 'a' is not valid so it wouldn't be accepted by the >> operator.

You seem to somehow expect that the input should convert the character to the ASCII code for that character in order to give you the integer-typed result you requested. This reasoning is not supported by the language.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Not `undefined behavior`, but the value has an `indeterminate state` because it was never set. Now accessing a value of indeterminate state is undefined behavior. – Martin York Nov 13 '12 at 15:06
3

In the first, you asked to input a character, so you got the first non-whitespace character in the stream. In the second, you asked to input an integer, so the stream skips whitespace (as it always does with >>) and attempted to parse an integer. Since "a" cannot be the start of an integral value, the stream set an error status (the failbit) and returned, without modifying input2. When you output the uninitialized variable, you have undefined behavior. (You should never use a variable you've input without first checking whether the input succeeded or not.)

From what you describe, it sounds like you are trying to input some binary format. To do that, you must open the stream in binary mode, ensure that it is imbued with the "C" locale, and then use istream::get or istream::read. (Of course, you have to know what the binary format is that you are reading, in order to be able to convert the unformatted bytes you read into the actual information you need.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
3

As e.g. Aardvard already has answered, you're seeing an arbitrary original value, in the C++ standard called an indeterminate value, because the input operation failed and input2 was not assigned a new value.

To output a decimal representation of the value of a char variable, simply convert it to int in order to direct the output stream to treat as integer.

The easiest way to convert it to int is to encourage an implicit promotion by using the variable in an expression, such as simply adding a + sign in front of it:

#include <iostream>
using namespace std;

int main()
{
    char const  ch  = 'a';
    cout << "'" << ch << "' = " << +ch << endl;
}

Output:

'a' = 97
Community
  • 1
  • 1
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
2

Because you are reading an integer at input2. a isn't an integer. Therefore nothing will be read, and the original value of input2 will be maintained.

In this case, it will be some random value, cause input2 isn't initialized.

You can check whether the read succeeded by checking cin.good()

Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151