exceptions thrown from overloaded stream operators

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 770 Views - Last Post: 26 December 2016 - 08:18 AM Rate Topic: -----

#1 bb8  Icon User is offline

  • D.I.C Regular

Reputation: 6
  • View blog
  • Posts: 311
  • Joined: 31-January 16

exceptions thrown from overloaded stream operators

Posted 10 November 2016 - 06:33 AM

i tried to do this:
std::istream& operator>>(std::istream& is, A& ob) {
    int i;
    std::cin >> i;

    if(i < std::numeric_limits<int>::min() || i > std::numeric_limits<int>::max()) {
      throw Error("out of range\n");
    }

    ob.value = i;
    is >> ob.value;
    return is;
  }

and then:
try {
    std::cin >> i1;
  }
  catch(Error e) {
    std::cerr << e.p;
  }
  std::cout << i1;

if i enter omething like 6597478653435431464535321532, what this code does is, it assigns some negative value to i1 and prints it and the window disappears quickly. i think i'm doing the throwing part incorrectly?

Is This A Good Question/Topic? 0
  • +

Replies To: exceptions thrown from overloaded stream operators

#2 jimblumberg  Icon User is offline

  • member icon

Reputation: 5344
  • View blog
  • Posts: 16,679
  • Joined: 25-December 09

Re: exceptions thrown from overloaded stream operators

Posted 10 November 2016 - 07:03 AM

Quote

it assigns some negative value to i1 and prints it and the window disappears quickly. i think i'm doing the throwing part incorrectly?

Not really. The extraction operator knows the acceptable values that it can retrieve and if the value entered is not a valid integer the stream will fail. You should be checking the status of cin, not the value read.

Also realize that you could, in this case just enable the extraction operator to throw a standard exception when the extraction fails. See this link for more information on enabling stream exceptions.

Jim
Was This Post Helpful? 0
  • +
  • -

#3 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2517
  • View blog
  • Posts: 4,001
  • Joined: 21-June 11

Re: exceptions thrown from overloaded stream operators

Posted 10 November 2016 - 08:50 AM

if(i < std::numeric_limits<int>::min() || i > std::numeric_limits<int>::max())


This condition can't ever possibly be true. It is not possible for an int variable to hold values below min() or above max() - that's what those limits mean.
Was This Post Helpful? 1
  • +
  • -

#4 bb8  Icon User is offline

  • D.I.C Regular

Reputation: 6
  • View blog
  • Posts: 311
  • Joined: 31-January 16

Re: exceptions thrown from overloaded stream operators

Posted 10 November 2016 - 09:19 AM

Then I should check the opposite condition? If i is in range (min, max)?
Was This Post Helpful? 0
  • +
  • -

#5 Peter O  Icon User is offline

  • D.I.C Regular

Reputation: 128
  • View blog
  • Posts: 299
  • Joined: 19-October 13

Re: exceptions thrown from overloaded stream operators

Posted 10 November 2016 - 09:45 AM

i will be set to std::numeric_limits<int>::max() if the input is larger than std::numeric_limits<int>::max().

i will be set to std::numeric_limits<int>::min() if the input is less than std::numeric_limits<int>::min().

What you can do is to check if the input operation failed and if so check if i equals one of the limits to decide if the input is out of range.

if (!(std::cin >> i))
{
	if (i == std::numeric_limits<int>::min() ||
	    i == std::numeric_limits<int>::max())
	{
		throw Error("out of range\n");
	}
	else
	{
		throw Error("Some other error\n");
	}
}

Was This Post Helpful? 1
  • +
  • -

#6 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2517
  • View blog
  • Posts: 4,001
  • Joined: 21-June 11

Re: exceptions thrown from overloaded stream operators

Posted 10 November 2016 - 09:55 AM

View Postbb8, on 10 November 2016 - 05:19 PM, said:

Then I should check the opposite condition? If i is in range (min, max)?


If you negate an always-false condition, you get an always-true condition. Or in other words: i will always be in range. It has to be by definition. You can not have an int that is not within the int range.
Was This Post Helpful? 0
  • +
  • -

#7 bb8  Icon User is offline

  • D.I.C Regular

Reputation: 6
  • View blog
  • Posts: 311
  • Joined: 31-January 16

Re: exceptions thrown from overloaded stream operators

Posted 13 November 2016 - 08:09 AM

i did as you said, but the thing here is that i need to write the user input to the istream, and i can't do this:
std::istream& operator>>(std::istream& is, A& ob) {
    int i;

    if(!(std::cin >> i)) {
      if(i == std::numeric_limits<int>::min() || i == std::numeric_limits<int>::max()) {
        throw Error();
      }
    }

    ob.value = i;
    is >> ob.value;
    return is;
  }

this way a user is asked to input twice, and the latest input is considered as ob.value

This post has been edited by bb8: 13 November 2016 - 08:10 AM

Was This Post Helpful? 0
  • +
  • -

#8 jimblumberg  Icon User is offline

  • member icon

Reputation: 5344
  • View blog
  • Posts: 16,679
  • Joined: 25-December 09

Re: exceptions thrown from overloaded stream operators

Posted 13 November 2016 - 11:21 AM

Why are you asking for input from std::cin, instead of using "is"? The purpose of the overload is to allow you to retrieve your type from the input stream provided.

As you've already been told you will never detect an int that is either larger than max() or smaller than min(), and remember min() or max() may be a valid entry. You need to check the state of the stream, not the value.

It usually doesn't matter much what actually caused the error, the fact that there is an error is all that matters. If you do need to know the exact cause of the error then you should be using a string or inputting a single character, not trying to use a numeric value. Strings and single characters are the basics of C++ input and output. You can retrieve almost anything without failure. Once you have safely retrieved the data you can then validate the information to determine if it is valid, before you try to convert the information to your desired type.

Jim
Was This Post Helpful? 1
  • +
  • -

#9 bb8  Icon User is offline

  • D.I.C Regular

Reputation: 6
  • View blog
  • Posts: 311
  • Joined: 31-January 16

Re: exceptions thrown from overloaded stream operators

Posted 14 November 2016 - 06:04 AM

that doesn't work either.
std::istream& operator>>(std::istream& is, A& ob) {
    int i;

    if(!(is >> i)) {
      if(i == std::numeric_limits<int>::min() || i == std::numeric_limits<int>::max()) {
        throw Error("out of range\n");
      }
    }

    return is;
  }


then:
try {
    std::cin >> i1;
  }
  catch(Error e) {
    std::cerr << e.msg;
  }

i input something like 54678864532645434153456786534341352413142534444447, no exception is thrown, whatever code is after this does its work (prints something), and the window closes immediately
Was This Post Helpful? 0
  • +
  • -

#10 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5928
  • View blog
  • Posts: 20,267
  • Joined: 05-May 12

Re: exceptions thrown from overloaded stream operators

Posted 14 November 2016 - 06:36 AM

It's not working because your code is still broken. You checked the stream state on line 4, but you'll only ever throw the exception if the integer value you have is out of range. But as previously explain, there is no way for an integer to hold a value that is out of range since that integer can only hold values that are in range. There is no way to check an integer to see if attempted to hold a value that is out of its range.

Try running this to see if the stream extractor is correctly putting the stream into an error state:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

int main()
{
    std::stringstream ss("54678864532645434153456786534341352413142534444447");
    int n;

    if (!(ss >> n))
        std::cerr << "bad!" << std::endl;
    else
        std::cout << "ok" << std::endl;

    return 0;
}


Was This Post Helpful? 2
  • +
  • -

#11 bb8  Icon User is offline

  • D.I.C Regular

Reputation: 6
  • View blog
  • Posts: 311
  • Joined: 31-January 16

Re: exceptions thrown from overloaded stream operators

Posted 14 November 2016 - 07:33 AM

the main thing i needed to understand was that i needed to check the state of the stream, not the input, and i understood that. the execution of the code almost continues, i mean whatever needs to get printed, gets printed, but whatever needs to be inputted, doesn't, cause the program terminates after the printing is done
Was This Post Helpful? 0
  • +
  • -

#12 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5928
  • View blog
  • Posts: 20,267
  • Joined: 05-May 12

Re: exceptions thrown from overloaded stream operators

Posted 14 November 2016 - 07:50 AM

Your options are:
- Run your program in the command line, instead of an IDE.
- If you are using Visual Studio, press Ctrl-F5 instead of F5. Visual Studio will keep the console window open for you.
- Use Code::Blocks instead of Visual Studio as your IDE. Code::Blocks automatically keeps the console window open for you.
- Add an extra line of code to way for the user to enter something.
Was This Post Helpful? 1
  • +
  • -

#13 jimblumberg  Icon User is offline

  • member icon

Reputation: 5344
  • View blog
  • Posts: 16,679
  • Joined: 25-December 09

Re: exceptions thrown from overloaded stream operators

Posted 14 November 2016 - 08:14 AM

Quote

that doesn't work either.

It would be helpful if you posted the smallest possible complete program that illustrates your problem. Your snippets are not providing enough information to be able to help you, for example how and where is "Error" defined?

Have you tried to remove that second if() statement in your function?


std::istream& operator>>(std::istream& is, A& ob) {
    int i;

    if(!(is >> i)) {
        throw Error("out of range\n");
    }

    return is;
}



If this doesn't seem to work then the problem is not with the throw, but something to do with the catch() or your "Error" class.

Jim
Was This Post Helpful? 0
  • +
  • -

#14 bb8  Icon User is offline

  • D.I.C Regular

Reputation: 6
  • View blog
  • Posts: 311
  • Joined: 31-January 16

Re: exceptions thrown from overloaded stream operators

Posted 14 November 2016 - 08:19 AM

I removed the 2nd if after Skydiver pointed that out. And I didn't notice I need to input on.value, not i. Now everything's fine. Thanks for the help, whoever helped.
Was This Post Helpful? 0
  • +
  • -

#15 bb8  Icon User is offline

  • D.I.C Regular

Reputation: 6
  • View blog
  • Posts: 311
  • Joined: 31-January 16

Re: exceptions thrown from overloaded stream operators

Posted 26 December 2016 - 07:06 AM

this is an old thread but i just felt that something was said incorrectly or i just didn't understand something correctly

Peter O said:

i will be set to std::numeric_limits<int>::max() if the input is larger than std::numeric_limits<int>::max().

i will be set to std::numeric_limits<int>::min() if the input is less than std::numeric_limits<int>::min().

, when i presented my work, i said i read that input will be set to std::numeric_limits<int>::max() if the input is larger than std::numeric_limits<int>::max(), and i was told that that's not correct. so what happens actually, then?
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2