[C++] Counters, error checking

Discussion in 'Web Design & Coding' started by onimkron, Nov 2, 2004.

  1. onimkron

    onimkron OSNN Senior Addict

    Messages:
    414
    I'm pretty much new to C++, having just started about 5 weeks back. I've gone through if, else, what, do statements, but one thing i'm currently fumbling on is probably so easily to implement, but I'm having difficulty with :)

    Code:
    // A program to calculate the area of a circle
    
    #include <iostream>
    using namespace std;
    
    int main ()
    {
    float radius;
    const double PI = 3.14159265359;
    unsigned count;
    
    count = 0;
    
    do
    {
    	if ( !cin.good() )
    	{
    		cerr << "Error" << endl;
    		cin.clear (0);
    		cin.ignore( 128, '\n' );
    		count = count + 1;
    		cout << "Test:" << count << endl;
    
    	}
    
    	cout << "Enter radius:";
    	cin >> radius;
    
    }
    	while ( !cin.good() );
    
    	radius = radius * radius;   // Get radius and multiply by itself (squared)
    
    	
    	cout << "Area of circle: " << PI * radius << endl;
    
    return 0;
    
    
    }
    
    Basically, the user inputs a number, and with it uses it as a radius and finds the area of a circle...works perfectly fine there. I've added an error checking bit, so it loops back to asking for a number if a character is entered (say, the letter 'a' instead of 1).

    I want to stop asking for a correct, numerical answer after 10 wrong attempts, hence the count interger statement near the top. However, although I can make it understand that there have been ten error attempts (the 'test' statement proves this), how do I make it so it just outpusts a cout statement along the lines of '10 attempts exceeded, closing program' etc?

    I apologise if this sounds long-winded. It just sounds like there's an actual simple solution for this, yet I can't just figure it out :confused:
     
  2. Reg

    Reg eXperienced!

    Messages:
    639
    Location:
    Arlington, TX
    Boy, it's been a while since I looked at C++. You could accomplish this by trying this:

    replace
    Code:
    
    if ( !cin.good() )
    	{
    		cerr << "Error" << endl;
    		cin.clear (0);
    		cin.ignore( 128, '\n' );
    		count = count + 1;
    		cout << "Test:" << count << endl;
    
    	}
    
    with
    Code:
    
      if(count == 10)
                {
                            cout << "10 Attempts Exceeded. Closing Program" << endl;
                            return 0;
                }
    
      elseif ( !cin.good() && count != 10)
    	{
    		cerr << "Error" << endl;
    		cin.clear (0);
    		cin.ignore( 128, '\n' );
    		count = count + 1;
    		cout << "Test:" << count << endl;
    
    	}
    
     
  3. onimkron

    onimkron OSNN Senior Addict

    Messages:
    414
    Ah, so I should be using if and else if statements, in conjunction with do and while statements? Never thought about that.

    Code:
    elseif ( !cin.good() && count != 10)
    This, I definitely did not consider. So, if the statement is 'not' good, and the count is 'not' equal to ten (not yet anyway), run the below statement. I'm going to try and adapt this to the code. :)

    I'll have to check it out when I get home, there's no compiler on this comp. Many thanks for the help :)
     
  4. X-Istence

    X-Istence * Political User

    Messages:
    6,498
    Location:
    USA
    Code:
    // A program to calculate the area of a circle
    
    #include <iostream>
    #include <cmath>
    // using namespace std; // This is the worst practice in the industry if there ever was one.
    
    int main ()
    {
            float radius; // I suggest using double. Floating point math can be inaccurate, for instance: if ( (1.0+1.0) == 2) could return false, instead of what you think it would return, a true.
            const double PI = M_PI; // The <cmath> header is so much fun! :P
            int count = 0; // This does not even have to be unsigned. You are not going to get huge numbers.
            
            do
            {
                    if ( !std::cin.good() )
                    {
                            count++;  // Just a ++ will do, it does the same thing, increment the counter by 1.
                            if (count == 10)
                            {
                                    std::cerr << "To many tries. Exiting Program" << std::endl;
                                    return EXIT_FAILURE;
                            }
                            std::cerr << "Error. Please enter a number" << std::endl;
                            std::cin.clear();
                            std::cin.ignore(128, '\n'); 
                            /*/*/ // std::cout << "Test:" << count << std::endl;
            
                    }
            
                    std::cout << "Enter radius:";
                    std::cin >> radius;
                    
                    if ( std::cin.good() )
                            break;
            
            } while ( true );
            
            radius = radius * radius;   // Get radius and multiply by itself (squared)
            std::cout << "Area of circle: " << PI * radius << std::endl;
            return EXIT_SUCCESS;
    }
    Reg it is bad practice to exit a program without returning an error code. Returning 0 means the program exited normally, and everything was fine, returning -1, or >0 means something was wrong.

    Eventhough for this app, it would not have matter to much, but if it were a program on the shell, and you would write a shell script, and then wanted to check if it exited successfully or it was a failure, your way would make the shell script think everything was fine.
     
  5. onimkron

    onimkron OSNN Senior Addict

    Messages:
    414
    I've always gone with namespace std, because that's basically what my lecturers and technicians told me to use; hence why I follow it that way. However, I can recognise some of the commands in yours, so I'll have a go again at it. Many thanks for all the help :)
     
  6. j79zlr

    j79zlr Glaanies script monkey Political User

    Messages:
    2,725
    Location:
    Chicago
    I don't see the point of this, and besides it is kind of confusing since A = pi*r*r

    radius = radius * radius; // Get radius and multiply by itself (squared)
    std::cout << "Area of circle: " << PI * radius << std::endl;

    Why not just:

    std::cout << "Area of circle: " << PI * radius * radius << std::endl;

    That would seem logically to make more sense.
     
  7. onimkron

    onimkron OSNN Senior Addict

    Messages:
    414
    That's just me messing around with some parameters, i'm new to this, so i'm trying to make the code as clean as possible, so I can actually understand it when I look back on it. I know it looks/sounds longhanded, but for now that's what i'm intending to do :)
     
  8. Reg

    Reg eXperienced!

    Messages:
    639
    Location:
    Arlington, TX
    As for returning 0 or a non-zero, the reason I didn't return a non-zero because there was no error, at least that he described. He just wanted to exit out after 10 tries. But, yes, that is correct practice.
     
  9. onimkron

    onimkron OSNN Senior Addict

    Messages:
    414
    I really appreciate all the help; I didn't expect it to be this complicated, but i'll take everything into account for future references. I also didn't know that my coding was this 'fragmented', but i'll just have to work on that.
     
  10. X-Istence

    X-Istence * Political User

    Messages:
    6,498
    Location:
    USA
    well, how about

    radius *= radius; :p

    I really just used it as it was there, and at the time i did not see the problem with it.

    But it really does not matter, i do however suggest adding () around mathematical expressions just to clarify that fact. But that is code astethics.
     
  11. X-Istence

    X-Istence * Political User

    Messages:
    6,498
    Location:
    USA
    Code:
    #include <iostream>
    #include <cmath>
    
    int main ()
    {
            float radius;
            const double PI = M_PI;
            int count = 0;
            
            do
            {
                    if ( !std::cin.good() )
                    {
                            count++;
                            if (count == 10)
                            {
                                    std::cerr << "To many tries. Exiting Program" << std::endl;
                                    return EXIT_FAILURE;
                            }
                            std::cerr << "Error. Please enter a number" << std::endl;
                            std::cin.clear();
                            std::cin.ignore(128, '\n');
                    }
            
                    std::cout << "Enter radius:";
                    std::cin >> radius;
                    
                    if ( std::cin.good() )
                            break;
            
            } while ( true );
            
            std::cout << "Area of circle: " << (PI * radius * radius) << std::endl;
            return EXIT_SUCCESS;
    }
    Just about not using namespace std, there is a reason for it:

    Lets say we have namespace std, and another namespace in this case named math. Now lets say we use:

    using namespace std;
    using namespace math;

    yet both those namespaces use the same function name sqrt to get the square root of a number, both take the same paramaters, but yet they both do it slightly different, and the one in the math class is faster by a few seconds, so you obviously want to use that one (Which is why you included it in the first place)

    now, in your code you put:

    sqrt(#);

    Now, which one do you mean? math::sqrt(); or std::sqrt();? Also, what if you have just namespace std, and you add your own function in some header file, and you want to use that, then the compiler has to start guessing at which one you want. Using std::function() stops that from hapening, as then then you have to specify the namespace it is.

    so then if you have std::somefunc(); and somefunc(), you can call somefunc() in your code, and know which function it will execute.
     
  12. X-Istence

    X-Istence * Political User

    Messages:
    6,498
    Location:
    USA
    I just added std:: to the front of the standard functions. Read my last post for an explenation.

    Personally i think that any teacher that does not know not to use "using namespace std" is not worth listening to, as mostly they will blab on about random crap which makes no sense in the first place./
     
  13. onimkron

    onimkron OSNN Senior Addict

    Messages:
    414
    I'm guessing they'll move on to not using namespace std in next semester, but it would be right to start learning alternatives now :)