Thread: Need help looping this switch statement

  1. #16
    Registered User
    Join Date
    Jan 2008
    Posts
    17
    I appreciate your help, but the 1000 level class i'm in would look at me funny if i showed up with week 10 stuff in my code when he hasnt even taught it yet. Thanks for everything, everyone!!

  2. #17
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Dunno, works for me.

    #include <iostream>

    and

    using namespace std;

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    When writing cases, typically it's more readable to indent the code:
    Code:
    case 'x':
    	// my code here
    	break;
    NOT
    Code:
    case 'x':
    // my code here
    break;
    The same goes for indentation for } and {. They should both be on the same level. They mark the start and end of a block and therefore should be on the same level because each "indentation level" is a guideline to us which code belongs where.

    About why your program just dies when typing a non-number entry... well, it's because of the poor design (IMO) of the STL.
    To solve it, a typical approach is to read a string, convert to number, and if number == 0 and the user did NOT enter 0, then it's an invalid number, otherwise just continue.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Taking this a little off topic here, but do you guys prefer to indent switch structures as:
    Code:
    switch (x)
    {
    case 0:
        foo();
        break;
    case 1:
        bar();
        break;
    default:
        baz();
    }
    or:
    Code:
    switch (x)
    {
        case 0:
            foo();
            break;
        case 1:
            bar();
            break;
        default:
            baz();
    }
    Assuming the former, would you also indent as:
    Code:
    switch (x)
    {
    case 0:
        {
            foo();
            bar();
        }
        break;
    default:
        baz();
    }
    or:
    Code:
    switch (x)
    {
    case 0:
        {
        foo();
        bar();
        }
        break;
    default:
        baz();
    }
    ?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #20
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Elysia View Post
    About why your program just dies when typing a non-number entry... well, it's because of the poor design (IMO) of the STL.
    To solve it, a typical approach is to read a string, convert to number, and if number == 0 and the user did NOT enter 0, then it's an invalid number, otherwise just continue.
    What on earth has cin, or his obvious logic error, got to do with STL??

    His program exits because 'option' is not equal to 9, as I already stated.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #21
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Nevermind, I misunderstood your question. It doesn't work for me.

    In response to laserlight, I prefer the second.
    Last edited by robwhit; 01-15-2008 at 01:12 PM.

  7. #22
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Taking this a little off topic here, but do you guys prefer to indent switch structures as:
    I prefer the second. The only problem is that IDEs have troubles deindenting the closing brace. But then, switches ain't good OOP anyway

    About why your program just dies when typing a non-number entry... well, it's because of the poor design (IMO) of the STL.
    To solve it, a typical approach is to read a string, convert to number, and if number == 0 and the user did NOT enter 0, then it's an invalid number, otherwise just continue.
    User input in a console program is a nuissance anyway (although may-be higher-level languages provide means for all the validation).
    It is not entirely impossible to write
    Code:
    while (!(cin >> x)) {
        //clear error
        //flush stream
        //display error prompt
    }
    And it is not impossible to turn this into a template function and have this problem solved for good

    how would I handle adding a y/n option making sure to be aware of syntax errors on behalf of the user?
    I haven't actually ever bothered to display a message "You must type either Y/N! Try again!!!" I have always just chosen to loop while Y or while not N, depending on whether exiting or continuing by accident would be a greater annoyance.
    But then, I'm the only user of my console programs...
    Last edited by anon; 01-15-2008 at 12:53 PM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #23
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by iMalc View Post
    What on earth has cin, or his obvious logic error, got to do with STL??
    It's part of the C++ libraries, is it not?

    His program exits because 'option' is not equal to 9, as I already stated.
    Yeah, but if you enter something other than 9, it won't terminate, yes? And "a" is not 9.

    As for the switch question, I typically do:
    Code:
    switch(something)
    {
    	case x:
    		// something;
    		break;
    	case y:
    	{
    		// something
    		break;
    	}
    	case z: /* something */; break;
    }
    Depends on the situation, really. Is the switch long? Then typically I try to compact it if there's just one line of code (plus break).
    Otherwise I use the non-brace version.
    If I use local variables and need to initialize or so, I use the brace type since it won't compile otherwise.
    The only problem I have is that Visual Studio default to:
    Code:
    switch(something)
    {
    	case y:
    		{
    			// something
    			break;
    		}
    }
    Which I find annoying. It's identical to if, so why the heck am I supposed to indent it again after the case?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #24
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Quote Originally Posted by anon View Post
    And it is not impossible to turn this into a template function and have this problem solved for good
    Good idea!
    Code:
    //
    // basic_input.h
    //
    // Contains the declaration/definition of console input helper functions
    // that make basic console input easier for new C++ programmers.
    //
    // basic_input:
    //    template<typename charT, typename traits, typename T>
    //      inline bool basic_input(std::basic_istream<charT,traits>& is,
    //                              T& x, charT delim)
    //    template<typename charT, typename traits, typename Allocator>
    //      inline bool basic_input(std::basic_istream<charT,traits>& is,
    //                              std::basic_string<charT,traits,Allocator>& x, charT delim)
    //    template<typename charT, typename traits>
    //      inline bool basic_input(std::basic_istream<charT,traits>& is,
    //                              charT* x, std::streamsize count, charT delim)
    //    template<typename charT, typename traits, typename T>
    //      inline bool basic_input(std::basic_istream<charT,traits>& is,
    //                              T& x)
    //
    //  Returns:
    //    bool - true if the input succeeded, false otherwise.
    //
    //  Effects:
    //    This function attempts to read from the input stream into the passed in
    //    variable up to the specified delimiter. If the data in the stream does
    //    not match the expected format of the variable type, or if the character
    //    following the data read in is not the delimiter, then the input fails.
    //
    //    On success, the variable x contains the inputted value. On failure, the
    //    variable x is cleared (i.e. default-initialized).
    //
    //    On success or failure, the input stream is left in a good state and all
    //    characters up to and including the delimiter are removed from the stream.
    //
    //    The delimiter defaults to '\n' if not specified.
    //
    //    If the variable type is char* (or some other character pointer), and the
    //    delimiter has not yet been reached prior to count characters being read
    //    in, then the input has failed and the array pointed to by the char* will
    //    be filled with count characters set to null.
    //
    //  Sample usage:
    //    int i;
    //    std::cout << "Enter an int: ";
    //    while (!bip::basic_input(std::cin, i))
    //        std::cout << "Invalid int! Try again: ";
    //
    //
    // ignore_line:
    //    template<typename charT, typename traits>
    //    inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is,
    //                                                         charT delim)
    //    template<typename charT, typename traits>
    //    inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is)
    //
    //  Returns:
    //    std::basic_istream<charT,traits>& - the stream passed in.
    //
    //  Effects:
    //    This function reads and discards all characters in the passed in input
    //    stream up to and including the first instance of the delimiter. The
    //    delimiter defaults to '\n' if not specified.
    //
    //  Sample usage:
    //    std::cout << "Press Enter to Close.\n";
    //    bip::ignore_line(std::cin);
    //
    
    #ifndef BASIC_INPUT_H_
    #define BASIC_INPUT_H_
    
    #include <istream>
    #include <ios>
    #include <string>
    #include <limits>
    
    namespace bip
    {
        template<typename charT, typename traits>
        inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is,
                                                             charT delim)
        {
            return is.ignore(std::numeric_limits<std::streamsize>::max(), delim);
        }
    
        template<typename charT, typename traits>
        inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is)
        {
            return ignore_line(is, is.widen('\n'));
        }
    
        template<typename charT, typename traits, typename T>
        inline bool basic_input(std::basic_istream<charT,traits>& is, T& x, charT delim)
        {
            std::ios::fmtflags old_flags = is.flags();
            if ((is >> std::noskipws >> x) && (is.eof() || is.get() == delim))
            {
                is.flags(old_flags);
                return true;
            }
            is.flags(old_flags);
    
            x = T();
            is.clear();
            ignore_line(is, delim);
            return false;
        }
    
        template<typename charT, typename traits, typename Allocator>
        inline bool basic_input(std::basic_istream<charT,traits>& is,
                                std::basic_string<charT,traits,Allocator>& x, charT delim)
        {
            if (std::getline(is, x, delim))
                return true;
    
            x.clear();
            is.clear();
            return false;
        }
    
        template<typename charT, typename traits>
        inline bool basic_input(std::basic_istream<charT,traits>& is,
                                charT* x, std::streamsize count, charT delim)
        {
            if (is.getline(x, count, delim))
                return true;
    
            if (is.gcount()+1 < count)
                memset(x, charT(), count);
    
            is.clear();
            ignore_line(is, delim);
            return false;
        }
    
        template<typename charT, typename traits, typename T>
        inline bool basic_input(std::basic_istream<charT,traits>& is, T& x)
        {
            return basic_input(is, x, is.widen('\n'));
        }
    }
    
    #endif  // BASIC_INPUT_H_
    Simple examples:
    Code:
    #include <iostream>
    #include <string>
    #include "basic_input.h"
    
    using namespace std;
    using namespace bip;
    
    int main()
    {
        // Reading integers
        int i;
        cout << "Enter an int: ";
        if (basic_input(cin, i))
            cout << "The number read in was: " << i << '\n';
        else
            cout << "Sorry, invalid int!" << '\n';
    
        // Reading doubles
        double d;
        cout << "Enter a double: ";
        while (!basic_input(cin, d))
        {
            cout << "Invalid double! Try again: ";
        }
        cout << "The double read in was: " << d << '\n';
    
        // Reading strings (one whole line at a time like getline)
        string s;
        cout << "Enter a line of text: ";
        basic_input(cin, s);
        cout << "The line of text read in was: " << s << '\n';
    
        // Pause the program
        cout << "Press Enter to Close.\n";
        ignore_line(cin);
    }
    More complex examples:
    Code:
    #include <iostream>
    #include <string>
    #include "basic_input.h"
    
    int main()
    {
        const std::streamsize cslen = 5;
        char cstyle[cslen];
        std::cout << "Enter a line of text: ";
        if (bip::basic_input(std::cin, cstyle, cslen, '\n'))
            std::cout << "The line of text read in was: " << cstyle << std::endl;
        else
            std::cout << "Sorry, invalid: " << cstyle << std::endl;
    
        std::string s;
        std::cout << "Enter a line of text: ";
        bip::basic_input(std::cin, s);
        std::cout << "The line of text read in was: " << s << std::endl;
    
        int i;
        std::cout << "Enter an int: ";
        if (bip::basic_input(std::cin, i))
            std::cout << "The number read in was: " << i << std::endl;
        else
            std::cout << "Sorry, invalid int!" << std::endl;
    
        double d;
        std::cout << "Enter a double: ";
        while (!bip::basic_input(std::cin, d))
        {
            std::cout << "Invalid double! Try again: ";
        }
        std::cout << "The double read in was: " << d << std::endl;
    
        std::wstring ws;
        std::wcout << L"Enter a line of text: ";
        bip::basic_input(std::wcin, ws);
        std::wcout << L"The line of text read in was: " << ws << std::endl;
    
        int wi;
        std::wcout << L"Enter an int: ";
        if (bip::basic_input(std::wcin, wi))
            std::wcout << L"The number read in was: " << wi << std::endl;
        else
            std::wcout << L"Sorry, invalid int!" << std::endl;
    
        double wd;
        std::wcout << L"Enter a double: ";
        while (!bip::basic_input(std::wcin, wd))
        {
            std::wcout << L"Invalid double! Try again: ";
        }
        std::wcout << L"The double read in was: " << wd << std::endl;
    
        std::cout << "Press Enter to Close.\n";
        bip::ignore_line(std::cin);
    }
    Last edited by jlou; 01-15-2008 at 02:02 PM.

  10. #25
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    switch only uses builtin types.
    Code:
    #include <iostream>
    int main()
    {
    using namespace std;
    
    	double num1, meters, feet, kilos, pounds, liters, gallons, kms, miles;
    	string option;
    
    	cout << "English/Metric Conversion Calculator v1.0" << endl;
    	cout << "-----------------------------------------" << endl;
    	cout << "1. Convert feet to meters" << endl;
    	cout << "2. Convert meters to feet" << endl;
    	cout << "3. Convert lbs. to kilograms" << endl;
    	cout << "4. Convert kilograms to lbs." << endl;
    	cout << "5. Convert gallons to liters" << endl;
    	cout << "6. Convert liters to gallons" << endl;
    	cout << "7. Convert square miles to square kilometers" << endl;
    	cout << "8. Convert square kilometers to square miles" << endl;
    	cout << "9. Quit" << endl << endl;
    	
    	do							// makes sure the loop is ran at least once
    	{	
    	cout << endl << "Please select the conversion type you want to perform:" << endl;
    
    	getline(cin, option);
    
    
    	if(option == "1")
    	{
    		cout << endl << "Enter the number of feet to convert to meters: ";
    		cin >> num1;
    		meters = num1 * 0.3048;
    		cout << endl << num1 << " feet is equal to " << meters << " meters." << endl;
    	}
    	else if(option == "2")
    	{
    		cout << endl << "Enter the number of meters to convert to feet: ";
    		cin >> num1;
    		feet = num1 * 3.2808399;
    		cout << endl << num1 << " meters is equal to " << feet << " feet." << endl;
    	}
    	else if(option == "3")
    	{
    		cout << endl << "Enter the number of pounds to convert to kilograms: ";
    		cin >> num1;
    		kilos = num1 * 0.45359237;
    		cout << endl << num1 << " lbs. is equal to " << kilos << " kilograms." << endl;
    	}
    	else if(option == "4")
    	{
    
    		cout << endl << "Enter the number of kilograms to convert to pounds: ";
    		cin >> num1;
    		pounds = num1 * 2.20462262;
    		cout << endl << num1 << " kilograms is equal to " << pounds << " lbs." << endl;
    	}
    	else if(option == "5")
    	{
    		cout << endl << "Enter the number of gallons to convert to liters: ";
    		cin >> num1;
    		liters = num1 * 3.7854118;
    		cout << endl << num1 << " gallons is equal to " << liters << " liters." << endl;
    	}
    	else if(option == "6")
    	{
    		cout << endl << "Enter the number of liters to convert to gallons: ";
    		cin >> num1;
    		gallons = num1 * 0.264172051;
    		cout << endl << num1 << " liters is equal to " << gallons << " gallons." << endl;
    	}
    	else if(option == "7")
    	{
    		cout << endl << "Enter the number of square miles to convert into square kilometers: ";
    		cin >> num1;
    		kms = num1 * 2.58998811;
    		cout << endl << num1 << " square miles is equal to " << kms << " square kilometers." << endl;
    	}
    	else if(option == "8")
    	{
    		cout << endl << "Enter the number of square kilometers to convert into square miles: ";
    		cin >> num1;
    		miles = num1 * 0.386102159;
    		cout << endl << num1 << " square kilometers is equal to " << miles << " square miles." << endl;
    	}
    	else
    	{
    		cout << "That is an invalid option.  Please choose again." << endl;
    	}
    	}
    	while(option != "9");			// keep looping to ask user as long as '9' isn't chosen
    	cout << "Thank you for using Conversion Calculator v1.0!" << endl;
    return 0;
    }
    Looks like Yarin gets the last laugh.

  11. #26
    Registered User
    Join Date
    Jan 2008
    Posts
    17
    Ok, so what do we agree is the final verdict? I've already established in my first post that I am not a programmer, I am an Industrial Engineer who took an entry level C++ class as an elective, and I just need some help with a few topics.

    I don't care if there is an easier way to write this program using templates or structs with arrays or a magic hat you can pull rabbits out of. We're not even at that point in class to use all of that stuff, so its a moot point anyway... plus rabbits have poor syntax...

    I also don't need people telling me my code is poorly written. If you think it is, I don't care. Indentation levels = I don't care. Does that effect the functionality? No. I appreciate the help on everything but all I want to know is how I add some code to allow the user to type in something other than 1-9 and get prompted for a selection again.

  12. #27
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by ravens199 View Post
    Ok, so what do we agree is the final verdict? I've already established in my first post that I am not a programmer, I am an Industrial Engineer who took an entry level C++ class as an elective, and I just need some help with a few topics.
    You've got the three choices Malcolm gave, which are all not really that different. None of us are going to care which one you use, and I can't find any others that I like.
    I don't care if there is an easier way to write this program using templates or structs with arrays or a magic hat you can pull rabbits out of. We're not even at that point in class to use all of that stuff, so its a moot point anyway... plus rabbits have poor syntax...
    Occasionally questions are interesting on their own, regardless of whether there is a use for them right this minute. Look at the contest forum.
    I also don't need people telling me my code is poorly written. If you think it is, I don't care. Indentation levels = I don't care. Does that effect the functionality? No.
    You will be extremely lucky if you never find out how wrong you are. It's obviously not as direct as, say, Python, but when you let the indentation make you miss a brace, or add an extra brace, or.... Plus, when assignment two adds to the source code of assignment one, and assignment three adds to the source of assignment two, and so on, being able to read, as you put it, will come in extremely handy. (I actually took a class -- granted, it was COBOL -- where we had one program. Ten programming assignments, starting at "read all the names" going through double-control-break programming or whatever, but you needed to have program n-1 in the code of program n. I've never gone that far myself.)

  13. #28
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Elysia View Post
    It's part of the C++ libraries, is it not?


    Yeah, but if you enter something other than 9, it won't terminate, yes? And "a" is not 9.
    C++ includes the Standard C++ Library which is similiar-to but not the same-as the STL (Standard template library). It is based on the STL. The commonly used correct term for it is SC++L. 'cin' doesn't involve templates either. It instead involves many overloads for different data types.

    Now it seems I was back-to-front with the while(option != 9) thing. So why did he say that typing something other than 9 was ending the program? I'm a little confused about that.
    I blame the heat. I just had a cold shower and I can't stop sweating.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  14. #29
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by iMalc View Post
    C++ includes the Standard C++ Library which is similiar-to but not the same-as the STL (Standard template library). It is based on the STL. The commonly used correct term for it is SC++L. 'cin' doesn't involve templates either. It instead involves many overloads for different data types.
    OK, so my bad. Whatever the C++ framework's name for all the things that ships with C++ is named.
    Anyway, I consider "cin" bad design.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #30
    Registered User
    Join Date
    Jan 2008
    Posts
    17
    Ok, I used one of Malcom's fixes to correct the mis-typing error. Thanks to everyone who helped, I appreciate it.

    Chris

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mutli Switch statement help
    By elwad in forum C Programming
    Replies: 9
    Last Post: 05-09-2009, 03:19 AM
  2. Switch statement / default:
    By kcpilot in forum C Programming
    Replies: 4
    Last Post: 12-02-2008, 03:14 PM
  3. Switch statement problem
    By jalex39 in forum C Programming
    Replies: 6
    Last Post: 03-08-2008, 04:05 PM
  4. switch statement issues...(undeclared identifiers)
    By mero24 in forum C++ Programming
    Replies: 2
    Last Post: 02-19-2005, 08:05 PM
  5. Efficiency with the switch() statement...
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 10-14-2001, 02:47 PM