tags:

views:

199

answers:

5

It is well known that cin is not typesafe (e.g. cin >> integer; and entering "fifty five" will cause it to flip out). I have seen many not-so-elegant ways to hand this, such as getlining a string and using sstream to convert it to a number, or looping with cin.fail() and clearing the stream and reentering it, etc. Is there any library or anyway to overload the extraction operator to make cin automatically typesafe?

+12  A: 

e.g. cin >> integer; and entering "fifty five" will cause it to flip out

No, this will not cause it to "flip out;" it will cause the fail state of the stream to be set, just like with any other stream. This doesn't mean that std::cin is not type-safe.

One option for handling errors reading from a stream would be to write a function template that performs the extraction, tests whether it succeeded, resets the error state on the stream if appropriate, and returns whether the extraction succeeded along with the result.

James McNellis
A: 

You could have a struct with a 'Type' field and an union field containing a string, double, bool and int. Then you could write an operator>> (ostream &, youtype &) overload which first reads the string from the ostream and tries to convert it to the most specific type ("1" becomes an int, "1.0" a double and so on ... ), setting the 'Type' field accordingly.

This would not be a perfect solution, but should be reasonably easy to re-use in other projects.

theDigtialEngel
A: 

Exception handling. That will prevent your example from "flip[ping] out".

thyrgle
+1  A: 

e.g. cin >> integer; and entering "fifty five" will cause it to flip out
[...]
Is there any library or anyway to overload the extraction operator to make cin automatically typesafe?

So std::cin fails when you want to read the wrong object from it.
Funny, here I always thought the fact that reading fails if you try to read the wrong type is what makes it type-safe.

Anyway, since you happen to disagree, which behavior would you suggest instead?

sbi
+3  A: 

It is well known that cin is not typesafe (e.g. cin >> integer; and entering "fifty five" will cause it to flip out).

Type safety doesn't mean what you seem to think it means. "fifty five" is a string. To convert it safely to a number is a complicated issue, if you really want to have a generic/portable implementation (what if it's "cinquante-cinq" [French] or "femtifem" [Norwegian])? You'd have to account for language, lexical parsing, grammatical correctness and so on. This is way beyond the scope of the STL.

std::istream is typesafe in the sense that if you try the example you gave, the stream will recognize the error ("know" it can't interpret the stream as an integer) and signal your client code the error in a way that can be checked for and handled in the client code.

As a comparison, if you use int i; sscanf("fifty five", "%s", &i); this will probably not raise any error, fill your i with garbage, and your program may crash later if it depends on i having a valid value (I may be wrong in this - I haven't used sscanf since high-school or so). Alternately, it may corrupt your program's memory if you have a format request that doesn't match the contents of your input string.

utnapistim