Thread: Handling a two character operator in a switch statement

  1. #1
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164

    Handling a two character operator in a switch statement

    Hi!
    I am setting up a program where the user enters two fractions and an operator (arithmetic or relational) and the program performs the operation and displays the result. I am having trouble figuring out how to handle the two character relational operators. Does anyone have any ideas.
    I tried:
    char oper1, oper2;
    cin >> oper1 >> oper2;
    but the program hangs when there isn't a second operator.
    Then I tried:
    string oper;
    getline(cin, oper);
    but my switch statement doesn't like that because oper is now a string.
    I was thinking about creating an enum with all the operators and using that in an if else, then using the eum type in my switch, but there has to be a better, shorter way. But, I am stumped.

    This is the code I have:
    Code:
    #include <string>
    using namespace std;
    
    #include "fractionType.h"
    
    int main()
    {
    	fractionType x;
    	fractionType y;
    	fractionType z;
    
    	string operStr;
    
    	cout << "\nThis program performs aritnmetic and relational operations"
    		 << "\non two fractions that you enter.";
    
    	const string MENU =  "\nThe operations that you can use are:"
    		 "\n Addition ------------------->  use '+'"
    		 "\n Subtraction ---------------->  use '-'"
    		 "\n Multiplication ------------->  use '*'"
    		 "\n Division ------------------->  use '/'"
    		 "\n Equal To ------------------->  use '=='"
    		 "\n Not Equal To --------------->  use '!='"
    		 "\n Less Than ------------------>  use '<'"
    		 "\n Greater Than --------------->  use '>'"
    		 "\n Less Than or Equal To ------>  use '<='"
    		 "\n Greater Than or Equal To --->  use '>='"
    		 "\n Or to QUIT -----------------> enter 'Q'"
    		 "\nEnter the required symbol when prompted."
    		 "\nEnter the first fraction in the form a/b: ";
    
    	cout << MENU;
    	cin >> x;
    	cout << "\nEnter the second fraction in the form a/b: ";
    	cin >> y;
    	cout << "\nEnter the operation symbol: ";
    	getline(cin, operStr);
    	cin.ignore();
    
    	while (oper != "Q" || oper != "q")
    	{
    		if
    		cout << endl;
    		switch(oper)
    			{
    			case '==':
    				{
    				if (x == y)
    					cout << x << " is Equal to " << y << endl;
    				else 
    					cout << x << " is Not Equal to " << y << endl;
    				break;
    				}//end case '=='
    			case '!=':
    				{
    				if (x != y)
    					cout << x << " is Not Equal to " << y << endl;
    				else 
    					cout << x << " is Equal to " << y << endl;
    				break;
    				}//end case '!='
    			case '<=':
    				{
    				if (x <= y)
    					cout << x << " is Less Than or Equal to " << y << endl;
    				else 
    					cout << x << " is Not Less Than or Equal to " << y << endl;
    				break;
    				}//end case '<='
    			case '>=':
    				{
    				if (x >= y)
    					cout << x << " is Greater Than or Equal to " << y << endl;
    				else 
    					cout << x << " is Not Greater Than or Equal to " << y << endl;
    				break;
    				}//end case '>='
    			case '+':
    				{
    					z = x + y;
    					cout << "The sum of " << x << " + " << y << " = " << z << endl;
    					break;
    				}//end case '+'
    			case '-':
    				{
    					z = x - y;
    					cout << "The difference of " << x << " - " << y << " = " << z << endl;
    					break;
    				}//end case '-'
    			case '*':
    				{
    					z = x * y;
    					cout << "The product of " << x << " * " << y << " = " << z << endl;
    					break;
    				}//end case '*'
    			case '/':
    				{
    					z = x / y;
    					cout << "The result of " << x << " / " << y << " = " << z << endl;
    					break;
    				}//end case '/'
    			default:
                    cerr << "\nInvalid operation choice, please try again!";
    			}//end switch
    		cout << MENU;
    		cin >> x;
    		cout << "\nEnter the second fraction in the form a/b: ";
    		cin >> y;
    		cout << "\nEnter the operation symbol: ";
    		getline(cin, oper);
    		cin.ignore();
    	}//end while
    }//end main
    Thanks for any input.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Okay...
    Two or more characters, like '==' isn't a char. It's a char* ('==' isn't even valid, because '' indicates a char, but this isn't a char, it's char*, so it should be "==").
    Switch expressions must be constant. You can't use a char* expression in there. A char ('+' for example) works fine, because it's basically an int.
    When comparing to a char*, you should use string functions or a string class. Never do a == "==".
    The easiest solution to your problem would be to input to a string (cin >> std::string), then compare that string with IF statements to find what the user typed.

    What should you do?
    - Input to a std::string (cin to a std::string).
    - Change your while loop argument to a an IF statement checking for "Q".
    - Remove your switch and replace with IF/ELSE checking against strings ("").

    These are my suggestions.
    Last edited by Elysia; 11-11-2007 at 12:53 AM.

  3. #3
    Registered User
    Join Date
    Sep 2007
    Location
    Arizona
    Posts
    164
    Thanks! Didn't even think of using the if else for the different operator options using a string.
    That was my last hurdle and this program is finished!
    Thanks again!

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Not a problem. Hope it works for you.

  5. #5
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by Elysia View Post
    '==' isn't even valid
    This compiles and runs as expected ( g++ )
    Code:
    #include <iostream> 
    #include <iomanip> 
    
    using namespace std;
    
    int main() {
    
        int ch[] = { '==', '!=', '>=' };
        
        for ( int i = 0; i < 3; ++i ) {
            switch(ch[i]) {
                case '==' : 
                    cout << hex << "0x" << setw(4) << setfill('0') << ch[i] << ": ==" << endl; 
                    break;
                case '!=' : 
                    cout << hex << "0x" << setw(4) << setfill('0') << ch[i] << ": !=" << endl; 
                    break;
                case '>=' : 
                    cout << hex << "0x" << setw(4) << setfill('0') << ch[i] << ": >=" << endl; 
                    break;
            }
        }
    }
    But then I don't think that this is very useful for the OP.
    Just wanted to point out that "multibyte character constants" are not illegal.
    Kurt

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by C++ Standard Final Draft
    An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharacter literal has type int and implementation-defined value.
    It's legal, but not portable.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I can't believe such a thing exists in the standard either.
    Code:
    char c = '!=';
    Gives a truncation warning in VC++ (ie, it discards the first '!' and initalizes the variable only with the last char value ('=').

  8. #8
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by Elysia View Post
    I can't believe such a thing exists in the standard either.
    Code:
    char c = '!=';
    Gives a truncation warning in VC++ (ie, it discards the first '!' and initalizes the variable only with the last char value ('=').
    That is because the the constant doesn't fit into a char. Try an int instead.
    Kurt

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Which is why I said '==' isn't legal (it's basically two bytes, but char is one byte).

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Which is why I said '==' isn't legal (it's basically two bytes, but char is one byte).
    Such a character literal appears to be legal, at least according to section 2.13.2 of the 2003 edition of the C++ Standard:
    Code:
    character-literal:
        'c-char-sequence'
        L'c-char-sequence'
    
    c-char-sequence:
        c-char
        c-char-sequence c-char
    
    c-char:
        any member of the source character set except
            the single-quote ', backslash \, or new-line character
        escape-sequence
        universal-character-name
    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

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, I suppose it is legal since it's possible to do
    Code:
    int c = '==';
    Which makes me think if the above code couldn't be redone with and int instead.

    UPDATE:
    It actually works with some manipulation:

    UPDATE2:
    New, safer code below.
    Last edited by Elysia; 11-11-2007 at 10:22 AM.

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    cin >> (char*)&oper;
    Now that's just a stack overflow waiting to happen.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    True enough. But so again, so is inputting to a variable without checking for errors a bad thing.
    The point wasn't to take errors and bad things into consideration, but to make it work.
    (I left out error checking on purpose.)

    UPDATE:
    Safer version:
    Code:
    int main()
    {
    	double x, y, z;
    	string operation;
    	string sx, sy;
    	int oper = 0;
    
    	cout << "\nThis program performs aritnmetic and relational operations"
    		 << "\non two fractions that you enter.";
    
    	const string MENU =  "\nThe operations that you can use are:"
    		 "\n Addition ------------------->  use '+'"
    		 "\n Subtraction ---------------->  use '-'"
    		 "\n Multiplication ------------->  use '*'"
    		 "\n Division ------------------->  use '/'"
    		 "\n Equal To ------------------->  use '=='"
    		 "\n Not Equal To --------------->  use '!='"
    		 "\n Less Than ------------------>  use '<'"
    		 "\n Greater Than --------------->  use '>'"
    		 "\n Less Than or Equal To ------>  use '<='"
    		 "\n Greater Than or Equal To --->  use '>='"
    		 "\n Or to QUIT -----------------> enter 'Q'"
    		 "\nEnter the required symbol when prompted.";
    
    	do
    	{
    		cout << MENU;
    		cout << "\nEnter the first fraction in the form a/b: ";
    		cin >> sx;
    		cout << "\nEnter the second fraction in the form a/b: ";
    		cin >> sy;
    		cout << "\nEnter the operation symbol: ";
    		cin >> operation;
    		cout << endl;
    		
    		if (atoi( sx.c_str() ) == 0 && sx.c_str()[0] != '0' || atoi( sy.c_str() ) == 0 && sy.c_str()[0] != '0')
    		{
    			cerr << "Invalid number entered. Please try again.\n\n";
    			continue;
    		}
    		x = strtod(sx.c_str(), NULL);
    		y = strtod(sy.c_str(), NULL);
    		const char* temp = operation.c_str();
    		oper = (int)temp[0] + (temp[1] << 8);
    
    		switch (oper)
    		{
    			case '==':
    			{
    				if (x == y)
    					cout << x << " is Equal to " << y << endl;
    				else 
    					cout << x << " is Not Equal to " << y << endl;
    				break;
    			}
    			case '!=':
    			{
    				if (x != y)
    					cout << x << " is Not Equal to " << y << endl;
    				else 
    					cout << x << " is Equal to " << y << endl;
    				break;
    			}
    			case '<=':
    			{
    				if (x <= y)
    					cout << x << " is Less Than or Equal to " << y << endl;
    				else 
    					cout << x << " is Not Less Than or Equal to " << y << endl;
    				break;
    			}
    			case '>=':
    			{
    				if (x >= y)
    					cout << x << " is Greater Than or Equal to " << y << endl;
    				else 
    					cout << x << " is Not Greater Than or Equal to " << y << endl;
    				break;
    			}
    			case '+':
    			{
    					z = x + y;
    					cout << "The sum of " << x << " + " << y << " = " << z << endl;
    					break;
    			}
    			case '-':
    			{
    					z = x - y;
    					cout << "The difference of " << x << " - " << y << " = " << z << endl;
    					break;
    			}
    			case '*':
    			{
    					z = x * y;
    					cout << "The product of " << x << " * " << y << " = " << z << endl;
    					break;
    			}
    			case '/':
    			{
    					z = x / y;
    					cout << "The result of " << x << " / " << y << " = " << z << endl;
    					break;
    			}
    			default:
                    cerr << "\nInvalid operation choice, please try again!";
    		}
    	}
    	while (oper != 'Q' || oper != 'q');
    	return 0;
    }
    Last edited by Elysia; 11-11-2007 at 10:22 AM.

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I would recommend, for portability and reliability that you use if-statements after selecting onthe first char.
    Code:
    switch(ch)
    {
        case '=':
            if (nextch == '=')
                ... // do equal check.
            else 
                ... // error - not valid operator
            break;
        case '!':
            if (nextch == '=')
               ... // do "not equal"
            else
               ... // error - not valid. 
    ...
    }
    It's a little bit extra code, but you don't rely on any complicated multibyte characters [which, by the way are dependant on the byte order in the architecture].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    OR could do like this (my favorite)

    Code:
    typedef void (OpFncPtr)(double, double, double&);
    
    void OpAdd(double x, double y, double& z)
    {
    	z = x + y;
    	cout << "The sum of " << x << " + " << y << " = " << z << endl;
    }
    
    void OpSub(double x, double y, double& z)
    {
    	z = x - y;
    	cout << "The difference of " << x << " - " << y << " = " << z << endl;
    }
    
    void OpMul(double x, double y, double& z)
    {
    	z = x * y;
    	cout << "The product of " << x << " * " << y << " = " << z << endl;
    }
    
    void OpDiv(double x, double y, double& z)
    {
    	z = x / y;
    	cout << "The result of " << x << " / " << y << " = " << z << endl;
    }
    
    void OpEqual(double x, double y, double&)
    {
    	if (x == y)
    		cout << x << " is Equal to " << y << endl;
    	else 
    		cout << x << " is Not Equal to " << y << endl;
    }
    
    void OpNEqual(double x, double y, double&)
    {
    	if (x != y)
    		cout << x << " is Not Equal to " << y << endl;
    	else 
    		cout << x << " is Equal to " << y << endl;
    }
    
    void OpLesserThan(double x, double y, double&)
    {
    	if (x < y)
    		cout << x << " is Lesser Than " << y << endl;
    	else 
    		cout << x << " is Not Lesser Than " << y << endl;
    }
    
    void OpGreaterThan(double x, double y, double&)
    {
    	if (x < y)
    		cout << x << " is Greater Than " << y << endl;
    	else 
    		cout << x << " is Not Greater Than " << y << endl;
    }
    
    void OpLessEqualThan(double x, double y, double&)
    {
    	if (x <= y)
    		cout << x << " is Less Than or Equal to " << y << endl;
    	else 
    		cout << x << " is Not Less Than or Equal to " << y << endl;
    }
    
    void OpGreatEqualThan(double x, double y, double&)
    {
    	if (x >= y)
    		cout << x << " is Greater Than or Equal to " << y << endl;
    	else 
    		cout << x << " is Not Greater Than or Equal to " << y << endl;
    }
    
    int main()
    {
    	double x, y, z;
    	string operation;
    	string sx, sy;
    	int oper = 0;
    	
    	// Create and fill function table
    	const int TableSize = ('>' + ('=' << 8));
    	OpFncPtr* FunctionTable[TableSize];
    	ZeroMemory(&FunctionTable, sizeof(FunctionTable));
    	FunctionTable['+'] = &OpAdd;
    	FunctionTable['-'] = &OpSub;
    	FunctionTable['*'] = &OpMul;
    	FunctionTable['/'] = &OpDiv;
    	FunctionTable['=' + ('=' << 8)] = &OpEqual;
    	FunctionTable['!' + ('=' << 8)] = &OpNEqual;
    	FunctionTable['<'] = &OpLesserThan;
    	FunctionTable['<'] = &OpGreaterThan;
    	FunctionTable['<' + ('=' << 8)] = &OpLessEqualThan;
    	FunctionTable['>' + ('=' << 8)] = &OpGreatEqualThan;
    
    	cout << "\nThis program performs aritnmetic and relational operations"
    		 << "\non two fractions that you enter.";
    
    	const string MENU =  "\nThe operations that you can use are:"
    		 "\n Addition ------------------->  use '+'"
    		 "\n Subtraction ---------------->  use '-'"
    		 "\n Multiplication ------------->  use '*'"
    		 "\n Division ------------------->  use '/'"
    		 "\n Equal To ------------------->  use '=='"
    		 "\n Not Equal To --------------->  use '!='"
    		 "\n Less Than ------------------>  use '<'"
    		 "\n Greater Than --------------->  use '>'"
    		 "\n Less Than or Equal To ------>  use '<='"
    		 "\n Greater Than or Equal To --->  use '>='"
    		 "\n Or to QUIT -----------------> enter 'Q'"
    		 "\nEnter the required symbol when prompted.";
    
    	do
    	{
    		cout << MENU;
    		cout << "\nEnter the first fraction in the form a/b: ";
    		cin >> sx;
    		cout << "\nEnter the second fraction in the form a/b: ";
    		cin >> sy;
    		cout << "\nEnter the operation symbol: ";
    		cin >> operation;
    		cout << endl;
    		
    		if (atoi( sx.c_str() ) == 0 && sx.c_str()[0] != '0' || atoi( sy.c_str() ) == 0 && sy.c_str()[0] != '0')
    		{
    			cerr << "Invalid number entered. Please try again.\n\n";
    			continue;
    		}
    		x = strtod(sx.c_str(), NULL);
    		y = strtod(sy.c_str(), NULL);
    		const char* temp = operation.c_str();
    		oper = (int)temp[0] + (temp[1] << 8);
    
    		if (FunctionTable[oper] == NULL)
    		{
    			cerr << "\nInvalid operation choice, please try again!";
    			continue;
    		}
    		try
    		{
    			FunctionTable[oper](x, y, z);
    		}
    		catch(...)
    		{
    			cerr << "\nInvalid operation choice, please try again!";
    			continue;
    		}
    	}
    	while (oper != 'Q' || oper != 'q');
    	return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using a character array in a switch question.
    By bajanElf in forum C Programming
    Replies: 10
    Last Post: 11-08-2008, 08:06 AM
  2. Getting the switch statement to work.
    By mtymightymike in forum C Programming
    Replies: 7
    Last Post: 10-15-2008, 06:32 PM
  3. switch case statement
    By stanlvw in forum C++ Programming
    Replies: 3
    Last Post: 02-26-2008, 05:06 AM
  4. switch statement that uses loop
    By mike in forum C++ Programming
    Replies: 2
    Last Post: 02-22-2002, 05:47 PM
  5. Uh-oh! I am having a major switch problem!
    By goodn in forum C Programming
    Replies: 4
    Last Post: 11-01-2001, 04:49 PM