Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Example : Not able to understand what is being done?

Tags:

c++

I found this link at http://www.parashift.com/c++-faq-lite/istream-and-ignore.html

which shows "How can I get std::cin to skip invalid input characters?"

Use std::cin.clear() and std::cin.ignore().

#include <iostream>
#include <limits>

int main()
{
  int age = 0;

  while ((std::cout << "How old are you? ")
         && !(std::cin >> age)) {
    std::cout << "That's not a number; ";
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  }

  std::cout << "You are " << age << " years old\n";
  ...
}
Of course you can also print the error message when the input is out of range. For example, if you wanted the age to be between 1 and 200, you could change the while loop to:
  ...
  while ((std::cout << "How old are you? ")
         && (!(std::cin >> age) || age < 1 || age > 200)) {
    std::cout << "That's not a number between 1 and 200; ";
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  }
  ...
Here's a sample run:
How old are you? foo
That's not a number between 1 and 200; How old are you? bar
That's not a number between 1 and 200; How old are you? -3
That's not a number between 1 and 200; How old are you? 0
That's not a number between 1 and 200; How old are you? 201
That's not a number between 1 and 200; How old are you? 2
You are 2 years old

I am not able to get how it is doing it > Can any one explain please?

I have doubts with :

while ((std::cout << "How old are you? ")
             && !(std::cin >> age)) 

How is it checking the valid entry? I mean to ask do expressions "std::cout << "How old are you?" and "!(std::cin >> age)" , return true or false which are being ANDed ?

another thing which is confusing is the usage,

std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

What are there purpose ? Searched on google about these functions but still I am not clear. Particularly, std::numeric_limits<std::streamsize>::max()

Can any one help? Thanks

like image 219
Gaurav K Avatar asked Apr 26 '13 10:04

Gaurav K


People also ask

What are the 3 types of error in programming?

When developing programs there are three types of error that can occur: syntax errors. logic errors. runtime errors.

What is a logical error in C give an example of it?

If our expectation is one thing and result output is other thing then that kind of error we said it as “Logical errors”. Let suppose if we want sum of the 2 numbers but given output is the multiplication of 2 numbers then this said to be Logical error. It can be detected by line by line debugging.

What is semantic error in C?

Errors that occur because the compiler is unable to understand the written code are called Semantic Errors. A semantic error will be generated if the code makes no sense to the compiler, even though it is syntactically correct. It is like using the wrong word in the wrong place in the English language.


2 Answers

The insertion and extraction operators << and >> on streams will return a reference to the stream itself. That's why you can string together insertions like so:

std::cout << "Hello, " << "World!";

First std::cout << "Hello, " returns a reference to std::cout and then you have the equivalent of std::cout << "World!".

The streams can also be converted to bool. This basically checks that the state of the stream is still okay. Nothing has failed. For example, you could do this:

if (std::cin) // ...

This would check if the std::cin stream is still in a good state.

Now let's look at the code you asked about:

while ((std::cout << "How old are you? ")
         && !(std::cin >> age))

The insertion into std::cout won't cause a failure. The only reason it's included here is so that it occurs every time before the input to age. The alternative would be to place it once before the while and once at the end of the while body.

After the insertion to std::cout is done, !(std::cin >> age) will be evaluated. This will first get the user to provide an age. Then two things can happen:

  1. If this fails in some way (perhaps the user enters characters rather than an integer), then the fail bit will be set. This means that the result of std::cin >> age will be converted to a bool which will be false. The ! will invert it to true. So because both the first and second condition were true, the body of the while loop will execute, telling the user that they entered an invalid value and the loop will iterate round again.

  2. if the input succeeds, the result of std::cin >> age will be true and ! will turn it to false. This means the body of the while loop will not execute and will not tell the user that they entered the incorrect value.

Now let's look at:

std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

This only happens in case 1 above, when the input failed. If a stream goes into a failure state, it will not accept any more insertions or extractions until the state has been cleared. that's what clear() does. Then the call to ignore says to extract all characters up to and including the next \n in the stream and discard them. This gets rid of the invalid input from the stream.

like image 99
Joseph Mansfield Avatar answered Nov 05 '22 04:11

Joseph Mansfield


while ((std::cout << "How old are you? ")        && !(std::cin >> age)) 

cout is a global object of class ostream and cin is a global object of class istream

These objects are used along the overloaded operators << (defined in ostream)and >> (defined in istream) to take input (by calling the functions defined for these operators)

The return type of operator<< is of type ostream& and that of operator>> is istream&. These are then converted to boolean values. See this.

Check this too for cin.ignore() and cin.clear()

like image 25
Suvarna Pattayil Avatar answered Nov 05 '22 06:11

Suvarna Pattayil