Handling perverse input

Started by
4 comments, last by JohnAD 21 years, 8 months ago
Hey all. I'm having a problem dealing with incorrect input. When I enter a lower case 'o' for example, or a floating point number like 9.75, it sends the program into an infinite loop. I've tried casting commands to an int with a temporary variable, but that doesn't seem to help. Here's the function:
    
///////////////////////////////////////////////////////////////////////////////

//edit_system()                                                              //

//                                                                           //

//Edit system information.                                                   //

//                                                                           //

///////////////////////////////////////////////////////////////////////////////

int edit_system(void) {

        int commands;                   //command variable

        int out;                        //return variable

        int hmin, hmax;                 //hab min and max

        int planet_num;                 //planet number

        int temp;                       //temp variable


        do {

                hmin = systems[current_sys].system_star.get_star_habitability_min();
                hmax = systems[current_sys].system_star.get_star_habitability_max();

                display_system_status();
                display_system();

                cout << "Enter command:";
                cout.flush();
                cin >> temp;
                commands = ((int) temp);
                cout << endl << endl;

//***DEBUG***

                cout << "command = " << commands << endl;
//***DEBUG***


                switch (commands) {

                        case 1: {

                                out = edit_star();
                                break;

                        }

                        case 2:
                        case 3:
                        case 4:
                        case 5:
                        case 6:
                        case 7:
                        case 8:
                        case 9:
                        case 10: {

                                if (!hmin) {

                                        cout << "You must create a star before";
                                        cout << " you can edit planets.";
                                        cout << endl << endl;
                                        break;

                                }

                                else {

                                        planet_num = (commands - 2);

                                        out = edit_planet(planet_num, hmin, hmax
);
                                        break;

                                }

                        }

                        default: {

                                out = 1;
                                commands = 0;  //in case of letter, break glass

                                break;

                        }

                }; // switch


        } while (commands); // do-while


        return out;

}
    
Any ideas? John. [edited by - JohnAD on August 23, 2002 4:18:46 PM]
Advertisement
You could just read in all input as a string and then parse out what you want. It''s a little time consuming, but it''s virtually crashproof, and you have more control over the errors that are thrown in response to poor input.

Later,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links

[twitter]warrenm[/twitter]

ZealousElixir:

Thanks! I''ll try that.

John.
quote:Original post by ZealousElixir
It''s a little time consuming, but it''s virtually crashproof, and you have more control over the errors that are thrown in response to poor input.

I don''t get it. Why do you have more control over the byte sequence when reading the same sequence of bytes from memory as from some other input device?

quote:Original post by JohnAd
When I enter a lower case ''o'' for example, or a floating point number like 9.75, it sends the program into an infinite loop.

That''s because your stream''s getting put into a fail-state. You can check the fail-state of cin using "if cin.fail()" and you can clear flags on the stream using "cin.clear()". I strongly recommend you read about both of these functions, and also ignore().
quote:Original post by SabreMan
I don''t get it. Why do you have more control over the byte sequence when reading the same sequence of bytes from memory as from some other input device?


You said it yourself: his input stream is falling into a fail-state because of bad data (seemingly because he''s reading a char or a float into an it). If he retrieved the input as a string, he could parse any kind of data, and output an appropriate error message if necessary, instead of checking for a lower level fail-state. Whatever works.

Later,
ZE.


//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links

[twitter]warrenm[/twitter]

quote:Original post by ZealousElixir
If he retrieved the input as a string, he could parse any kind of data, and output an appropriate error message if necessary, instead of checking for a lower level fail-state.

It's the same deal in-memory. He still has to convert the data to the target types and deal with any conversion errors. I don't see how having an "xyz" where an int is expected is any easier to handle from a string(stream) than from an input stream. If he uses a stringstream, he has to cater for the same fail states. If he uses something lower level, he'll end up creating something which simulates fail states on nonsensical conversions, and needs to tell the user they entered something wrong.

[edited by - SabreMan on August 23, 2002 8:02:39 PM]

This topic is closed to new replies.

Advertisement