Returning something to main() so it can end the program

Pages: 12
Now I'm rewriting my calculator using the stuff you taught me and I ran into a problem, if I use:

1
2
3
4
5
6
7
void getx(signed long long int &xprime)
{
    if (!(cin >> xprime) || (xprime < 2) || ((xprime - floor(xprime)) != 0))
    {
        throw runtime_error{"You have to enter a natural number larger than 1!"};
    }
}


It doesn't throw the error if I enter, let's say, 3.4. Instead it registers xprime as 3 and carries the 3.4 to the next cin, which is choosing what to do next (you have to enter 0, 1, ... 6, 7), then it throws an error like it's supposed to. How can I throw an error if a number entered is not an integer?
That exact problem is why I wrote this article:
http://www.LB-Stuff.com/user-input
In the line istringstream is {line}; I get an error error: in C++98 'is' must be initialized by constructor, not by '{...}'. What is it supposed to do anyway?

Also, for every usage of throw runtime_error{"Message"}; I get a warning warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]. Does this mean anything?

EDIT: My compiler was using C++98, changed it to C++11...
Last edited on
Yes, it means you forgot to enable C++14, the latest version of C++. Adjust your command line flags so the compiler receives the -std=c++14 option, or if that doesn't work, use -std=c++11 for C++11 instead.

As for why your compiler defaults to using a version of C++ from almost two decades ago, I have no idea.
-std=c++14 doesn't work, I can only use -std=c++11. Is that ok?

Also my implementation of your code doesn't work for me:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void getxy(long double &x, long double &y)
{
    string line;
	int num;
	while((cout << "Enter x and y:" << endl) && getline(cin, line))
	{
		istringstream is {line};
		if((is >> num) && !(is >> line))
		{
			break;
		}
		cerr << "Invalid input, try again." << endl;
	}
}


Do I need 2 separate functions, one to get x and another to get y, or can it be done in 1? I need your code to do the same as cin >> x >> y; if that's possible.

P. S. Going to sleep now, so won't be able to answer you any time soon. Thanks for the help!
You should make a dedicated function for reading a single value, and in your getxy() function you would just call it twice.
So I think this should work, but it doesn't.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void getxy(long double &x, long double &y)
{
    cout << "Enter x:" << endl;
    input(x);
    cout << "Enter y:" << endl;
    input(y);
}

void input(long double &x)
{
    string line;
	int num;
	while(getline(cin, line))
	{
		istringstream is {line};
		if((is >> num) && !(is >> line))
		{
			break;
		}
		cerr << "Invalid input, try again." << endl;
	}
}


And in my main function I call have this:

1
2
3
4
5
6
7
if (a==1)
{
    cout << endl << "x + y" << endl;
    getxy(x, y);
    cout << endl << "Sum: " << addition(x, y) << endl << endl;
    return main();
}


I think from my main function I'm passing x and y's references to getxy(), and it is passing those references to input()? But it doesn't work, after "Enter x:" it immediately says "Invalid input, try again.". Also, how would your code have to be changed, to accept, let's say, only single letters instead of numbers?
> return main();

A program shall contain a global function called main, which is the designated start of the program.
...
The function main shall not be used within a program.
- IS (The International Standard for C++)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>

double get_number( const char* prompt = "enter a number: " )
{
    std::cout << prompt ;
    double number ;

    if( std::cin >> number ) return number ;

    else
    {
        std::cout << "invalid input. please try again\n" ;

        // http://www.cplusplus.com/reference/ios/ios/clear/
        std::cin.clear() ; // clear input error state

        // http://www.cplusplus.com/reference/istream/istream/ignore/
        std::cin.ignore( 1000, '\n' ) ; // throw away the current line

        return get_number(prompt) ; // try again
    }
}

void get_xy( double& x, double& y )
{
    x = get_number( "enter x: " ) ;
    y = get_number( "enter y: " ) ;
}

double sum( double a, double b ) { return a+b ; }

bool once_again()
{
    std::cout << "once again (y/n)? " ;
    char again ;
    return std::cin >> again && ( again == 'y' || again == 'Y' ) ;
}

int main()
{
    do
    {
        double x ; // use double as the default floating pint type
        double y ;
        get_xy(x,y) ;

        std::cout << x << " + " << y << " == " << sum(x,y) << '\n' ;
    }
    while( once_again() ) ;
}
That's a well written program, I'll use it as an example for building similiar stuff. Thank you for taking the time to explain my mistakes!
Merged your codes together, LB and JLBorges, and it does exactly what I want and expect it to do. Thank you both for the help!
Topic archived. No new replies allowed.
Pages: 12