C++ switch statement , how does this work - c++

#include <iostream>
#include <sstream>
int main(int argc, char* argv[]) {
if ( argc != 2 ) {
std::cout << "usage: " << argv[0] << " <n> " << std::endl;
return 0;
}
std::stringstream strm;
strm << argv[1];
int count = 0;
int number;
strm >> number;
switch ( number ) {
case 0: ++count;
case 1: ++count;
case 2: ++count;
case 3: ++count;
case 4: ++count;
}
std::cout << "count: " << count << std::endl;
return 0;
}
I know this is a novice question, but i just started with C++. I took a game design course and this is the first example prof has on the SVN. When I run the prog after compiling,
./run 4
(i.e. I give argument 4) I get an output: count: 1
./run 3
I get an output: count: 2
./run 1
count: 4
./run 0
count: 5
Since count is initialized to 0, how come ./run 1 gives 4 or ./run 0 give count 5.
I am really sorry for such a silly question, but I would appreciate any explanation.
Thanks in Advance
Regards

With a switch statement, when control is passed to a case label, the code will continue on through all other case labels until a break or return (or other flow control mechanism) is encountered. This can be useful for unifying logic of specific cases, and can also be used for more complicated tasks. See for example: a Duff's Device.

A switch statement defines where to enter a set of code.
switch ( number ) {
case 0: ++count; //entrance point with number= 0
case 1: ++count; //entrance point with number= 1
case 2: ++count; //entrance point with number= 2
case 3: ++count; //entrance point with number= 3
case 4: ++count; //entrance point with number= 4
}
Inherently there is no exit except for getting to the end of the switch. However, it is possible to add a "break;" statement anywhere under a case to cause the code to exit the switch early (or break out of scope).
Additionally, but slightly off topic, the keyword "default" should be used in a case statement. The default keyword is called when the number doesn't have a defined case. Example, using the case above, is if someone sent the number 6 to the case.

Related

c++ fizzbuzz switch statement?

I'm trying to see if I can make a fizzbuzz c++ switch statement. I'm getting an error saying i is not usable in a const expression. Does that mean I can't make this thing work? Or is there a work around? Here's my code.
#include <iostream>
using namespace std;
int main() {
for(int = 1; 1 <= 100; i++){
switch(true){
case(i % 3 == 0 & i % 5 == 0):
cout << "fizzbuzz" << endl;
break;
case(i % 3 == 0):
cout << "fizz" << endl;
break;
case(i % 5 == 0):
cout << "fizz" << endl;
break;
default:
cout << i << endl;
}
}
}
If you really want to use switch/case then you could do it like this:
switch (i % 15)
{
case 0 : cout << "fizzbuzz\n"; break;
case 5:
case 10: cout << "buzz\n"; break;
case 3:
case 6:
case 9:
case 12: cout << "fizz\n"; break;
default: cout << i << "\n"; break;;
}
There are a couple of fundamental problems with how you're using switch/case.
The expected way to use it is to have the switch refer to a variable or expression, then the case sections refer to constant values.
Instead what you're doing is switch(true) which doesn't make any sense, even though it compiles. It's equivalent to switch(1). So in that case only case 1: would ever apply.
You cannot use expressions for case. These must be constant integer values. So for example you can either plain integers case 0:, or also commonly pre-processor defines case FIZZBUZZ:.
As stated in the comments, several times, you cannot always use a switch() statement like a if statement and there are several other issues with your code. I am not going to give you the right answer as I don't believe that will help you the most.
Here are some notes:
1) Instead of a switch you should use if, else if, and else statements.
2) In C++ a and is expressed as && not &
3) A for loop is declared like for(int i = 0; i <= 100; i++)
You should watch/read some simple tutorials on how to code C++ as it is important you understand these basics.

Program that displays all multiples of 7 between 1 and 100 C++

How to write this program with switch condition statement instead of if?
#include <iostream>
using namespace std;
int main() {
int i;
for (i = 1; i <= 100; i++) {
if ((i % 7 == 0) && (i > 0)) {
cout << i << endl;
}
}
return 0;
}
The code you're looking for should be something like this:
#include <iostream> // this is for std::cin and std::cout (standard input and output)
using namespace std; // to shorten std::cout into cout
int main() {
cout << "multiples of 7 lower than 100 are:" << endl;
for ( int i=1 ; i<=100 ; i++ ) {
switch ( i%7 ) {
case 0: // this case 0 is similar to if ( i%7 == 0 )
cout << i << " ";
break;
default:
break;
}
}
cout << endl;
return 0;
}
The output will then be:
multiples of 7 lower than 100 are:
7 14 21 28 35 42 49 56 63 70 77 84 91 98
Here you are:
#include <iostream>
int main()
{
for (int i = 1; i<=100; i++)
{
switch(i % 7)
{
case 0:
std::cout << i << std::endl;
break;
default:
break;
}
}
return 0;
}
Online compilation: http://ideone.com/uq8Jue
It sounds like you are a little unfamiliar with a switch statement. A switch statement is like an if-else statement, except that it isn't a Boolean argument. So essentially it asks: Tell me the value of . And then for each case (possible outcome), it has a follow up action.
So you want to ask: tell me the value of the number, modulus 7. If it is zero, add one to the counter. If it is 1, do .
So your code should have a general structure of:
Switch(i%7):
Case 0{increment counter or display to std. out or store in array}
Case 1{other action}
It is possible to replace the if statement with switch/case statement for your case. But I think you have some misunderstanding about where to use if and where switch/case statements. I will suggest you use this statement as they are used in real life.
Use if, if you're going to check the condition. For example:
if (a > b){...} or if (a == 7){...} or if (functionReturnsTrue()){...}
The switch/case statement could be used when you have a set of conditions and the logic is different for each element in that set. For example:
enum HttpMethod {
GET,
POST,
PUT,
DELETE,
};
...
void handleHttpRequest(HttpRequest req)
{
...
switch(req.getHttpMethod())
{
case GET: handleGETRequest(req); break;
case POST: handlePOSTRequest(req); break;
case PUT: handlePUTRequest(req); break;
case DELETE: handleDELETERequest(req); break;
default: throw InvalidHttpMethod(); // in case when noone corresponds to the variable
}
}
Of course, you can write the same using if statement, but switch/case statement also have some compilation effects. When you switch the variable of enum type, you might get a compiler warning at least, if you dont check your variable for all possible flows.

My program doesn't quite work right

#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
string numString(int k)
{
string str;
switch (k) {
case 0 : str ="ZERO"; break;
case 1 : str ="ONE"; break;
case 2 : str ="TWO"; break;
case 3 : str ="THREE"; break;
case 4 : str ="FOUR"; break;
case 5 : str ="FIVE"; break;
case 6 : str ="SIX"; break;
case 7 : str ="SEVEN"; break;
case 8 : str ="EIGHT"; break;
case 9 : str ="NINE"; break;
}
return str;
}
int main(int argc, char** argv) {
int value;
int digit;
cout << "Enter a number: ";
cin >> value;
while (value > 0 )
{
digit = value % 10;
value = value / 10;
cout << numString(value) << endl;
}
return 0;
}
My program is supposed to prompt the user for an integer value read that value, and output the word equivalent of each digit
For example if "9502" was entered it would output "NINE FIVE ZERO TWO"
Yet mine only outputs "NINE ZERO" and then stops. I can't figure out what I'm doing wrong, any help at all is greatly appreciated.
Yet mine only outputs "NINE ZERO" and then stops.
That's literally what you told it to do!
while (value > 0 )
You'll have to find some other way to signal a "termination" condition if zero is supposed to be valid.
Traditionally we let the system's own end-of-file signalling take care of that for us, so that we don't have to "reserve" some otherwise-valid input and use it as a signal flag.
while (cin >> value) {
digit = value % 10;
value = value / 10;
cout << numString(value) << endl;
}
That fixes your loop, although unfortunately your maths are still wrong and your output is not what you intend. In fact, your digit variable is not used at all. I am not going to spoonfeed an algorithm here: you'll have to work out on paper how to achieve the business logic. :)
This is an analysis of your program using the input 9502.
Iteration 1, in main:
(new) value = 9502 / 10;
(new) digit = 9502 % 10;
value == 950;
digit == 2;
call numString(950);
// Note: there is no case for 950 in numString so an empty string is returned.
Iteration 2, in main:
(new) value = 950 / 10;
(new) digit = 950 % 2;
value == 95;
digit == 0;
call numString(95);
// Note: there is no case for 95 in numString so an empty string is returned.
The above iterations and variable values can be obtained with pen & paper (or a note pad). You can also do the same with something called a debugger.
I hope this helps.

Evaluate postfix using a stack in C++

#include <iostream>
#include <sstream>
#include <stack>
#include <limits>
#include <string>
using namespace std;
int main()
{
string input;
cout << "Enter a postfix expression: " << endl;
getline(cin, input);
int operand1, operand2, result,number;
stack<char>operation;
stringstream temp;
int i=0;
while (i < input.length())
{
if (isdigit(input[i]))
{
operation.push(input[i]);
}
else
{
operand2 = operation.top();
temp << operation.top();
operation.pop();
operand1 = operation.top();
temp << operation.top();
operation.pop();
switch(operand1,operand2)
{
case '+': result=operand1 + operand2;
break;
case '-': result=operand1 - operand2;
break;
case '*': result=operand1 * operand2;
break;
case '/': result=operand1 / operand2;
break;
}
operation.push(result);
}
i++;
}
cout << "The result is: "<<temp.str()<<endl;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return 0;
}
I've changed the code and managed to obtain the "pop" value, but the operation didn't work.
You probably meant
switch(input[i])
instead
switch(operation.top())
Update response to code changes
I can confirm you changed the code, but not in a good way.
The code mostly has all the flaws it already had, and a few more.
What good is that you now combine the operands into a stringstream?
You now switch on (operand1,operand2)...
both are uninitialized
(operand1,operand2) means basically (operand2) in this context (sequence operator)
your branch labels are ... operators (+-/*)
you now print a final result which is the concatenation of all digits in the input (if you ever reach the end of the program without crashing)?
Among the things that were wrong before, and should still be fixed
the mental model of a stack calculator.
numbers (integers) are the operands (so 9, 100, 39829 are valid operands)
+-/* are the operators (operators operate on the operands)
the stack is an operand stack, not an operator stack (operators do not have to be remembered, because they are evaluated immediately)
numbers consist of 1 or more digits (0123456789) in a row; so you'd need to read several characters before you can 'push' a number on the operand stack
the operators +-/* take 2 operands, so any operation on a stack of size<2 is an error (you need to check that or the program will crash while trying to access memory that doesn't exist or contains rubbish).
That should be enough to get you started.
Two things I do think are positive:
You program compiles. +1 for you actually using a compiler there :)
You took the repeated operation.push(result) out of the switch so it isn't duplicated anymore. +1 for coding style ...
I hope you can gather from this that the code isn't very good (to put it mildly), and I really think some basic exercises are in order:
1. write a simple for loop that prints numbers 1 to 10 to the console
1. write a simple while loop that prints words entered by the user
1. use a simple loop to print all numbers between 1 and 50 that are multiples of 7
1. use a switch statement to print "yes" whenever the user enters one of the letters a, b, k, or z
2. make a simple loop that only prints the input character for every character that follows the identical (so 'abccdefgghijkllmabcdd' would become 'cgld')
1. use the same loop but this time print every word that immediately follows the identical word (so "no, no, you should not pop, pop, but push, pop" becomes "no pop")
That should give you a feel for how things really work, without the guesswork or the 'magic factor'.
Oh, and don't forget, I implemented the whole thing for you below. I don't suggest you blindly copy it (it will be rather obvious to your teacher :)) but it is there for you to take a peek if you want to know, what I mean with all my words above :)
You are pushing loose digits, not parsed numbers
In line 31 you pop a possibly empty stack (resulting in segfault unless you use the debug-mode STL flags on your compiler)
Just for fun:
#include <iostream>
#include <stack>
#include <vector>
#include <limits>
#include <string>
#include <stdexcept>
#include <iterator>
#include <fstream>
using namespace std;
template <class T>
static void dumpstack(std::stack<T> s/*byval!*/)
{
std::vector<T> vec;
while (!s.empty())
{
vec.push_back(s.top());
s.pop();
}
std::copy(vec.rbegin(), vec.rend(), std::ostream_iterator<int>(std::cout, " "));
}
class calc
{
private:
std::stack<int> _stack;
int _accum;
bool _pending;
void store(/*store accumulator if pending*/)
{
if (_pending)
{
_stack.push(_accum);
_pending = false;
_accum = 0;
}
}
public:
calc() : _accum(0), _pending(false)
{
}
void handle(char ch)
{
switch (ch)
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
_pending = true;
_accum *= 10;
_accum += ch-'0';
break;
case '+': case '-': case '/': case '*':
{
store();
if (_stack.size()<2)
throw std::runtime_error("stack underflow");
int op2 = _stack.top(); _stack.pop();
int op1 = _stack.top(); _stack.pop();
switch (ch)
{
case '+': _stack.push(op1 + op2); break;
case '-': _stack.push(op1 - op2); break;
case '/': _stack.push(op1 / op2); break;
case '*': _stack.push(op1 * op2); break;
}
// feedback to console:
std::cout << std::endl << "(evaluated: " << op1 << " " << ch << " " << op2 << " == " << _stack.top() << ")" << std::endl;
dump();
}
break;
default:
store(); // todo: notify of ignored characters in input?
}
}
void dump() const
{
dumpstack(_stack);
}
};
int main()
{
cout << "Enter postfix expressions: " << endl;
calc instance;
try
{
while (std::cin.good())
{
char ch = std::cin.get();
instance.handle(ch);
}
std::cout << "Final result: ";
instance.dump();
return 0;
} catch(const std::exception& e)
{
std::cerr << "E: " << e.what() << std::endl;
return 255;
}
}
Test output: (note that you can continue with the remaining, partially evaluted, stack after pressing carriage return)
Enter postfix expressions:
1 2 3 +4 * - / 1333 *
(evaluated: 2 + 3 == 5)
1 5
(evaluated: 5 * 4 == 20)
1 20
(evaluated: 1 - 20 == -19)
-19 E: stack underflow
There are many things wrong with the code, starting with parsing of the input expression. The actual crash is most probably due to the fact that if you input something like "12+" you will push '1' and '2' into the stack (note: characters 1 and 2, not values 1 and 2!!!) and then try to extract two operands and an operator that you never inserted into the stack.
On parsing the input, you are reading character by character, and only using the first digit, the parsing is not able to handle spaces or any other separator... Try to break the problem in two: parsing and processing. The problem of parsing can be tackled by not using the actual values read, but just printing them (or storing in some form and then printing the whole read expression), and can be a first step. Ensure that the parser is able to deal with common expressions like "1 2 +", "10 20 +", "1 2+", " 1 2 + " (note the different positions of spaces) in a robust way. And that it fails gracefully to parse expressions like " +", "1 +", "1 2 ++"... You can never trust user input, they will make mistakes and that should not bring your program to its knees.
Once you are sure that you are able to parse the input, start on the actual algorithm. Make it robust against invalid user inputs that you might have not been able to tackle before, like "10 0 /" and do the actual processing.
Learn to use the debugger, it will help you understand when things go south what are the reasons. The debugger would take less than one second to point at the specific problem in your code above, it will not tell you why it died, but it will show you how it died and what the state of the program was there. If my hunch is correct, then it will point you at the operation.top() instruction as the culprit, and you will be able to see that you were trying to extract more elements than were inserted. Execute a part of your program step by step to understand what it is actually doing, and you will notice that when you read "12+" you are actually storing two seemingly unrelated integers into the stack (the ASCII values of '1' and '2'...

Grouping switch statement cases together?

I may be over looking something but is there a simple way in C++ to group cases together instead of writing them out individually? I remember in basic I could just do:
SELECT CASE Answer
CASE 1, 2, 3, 4
Example in C++ (For those that need it):
#include <iostream.h>
#include <stdio.h>
int main()
{
int Answer;
cout << "How many cars do you have?";
cin >> Answer;
switch (Answer)
{
case 1:
case 2:
case 3:
case 4:
cout << "You need more cars. ";
break;
case 5:
case 6:
case 7:
case 8:
cout << "Now you need a house. ";
break;
default:
cout << "What are you? A peace-loving hippie freak? ";
}
cout << "\nPress ENTER to continue... " << endl;
getchar();
return 0;
}
AFAIK all you can do is omit the returns to make things more compact in C++:
switch(Answer)
{
case 1: case 2: case 3: case 4:
cout << "You need more cars.";
break;
...
}
(You could remove the other returns as well, of course.)
Sure you can.
You can use case x ... y for the range
Example:
#include <iostream.h>
#include <stdio.h>
int main()
{
int Answer;
cout << "How many cars do you have?";
cin >> Answer;
switch (Answer)
{
case 1 ... 4:
cout << "You need more cars. ";
break;
case 5 ... 8:
cout << "Now you need a house. ";
break;
default:
cout << "What are you? A peace-loving hippie freak? ";
}
cout << "\nPress ENTER to continue... " << endl;
getchar();
return 0;
}
Make sure you have "-std=c++0x" flag enabled within your compiler
No, but you can with an if-else if-else chain which achieves the same result:
if (answer >= 1 && answer <= 4)
cout << "You need more cars.";
else if (answer <= 8)
cout << "Now you need a house.";
else
cout << "What are you? A peace-loving hippie freak?";
You may also want to handle the case of 0 cars and then also the unexpected case of a negative number of cars probably by throwing an exception.
PS: I've renamed Answer to answer as it's considered bad style to start variables with an uppercase letter.
As a side note, scripting languages such as Python allow for the nice if answer in [1, 2, 3, 4] syntax which is a flexible way of achieving what you want.
You can't remove keyword case. But your example can be written shorter like this:
switch ((Answer - 1) / 4)
{
case 0:
cout << "You need more cars.";
break;
case 1:
cout << "Now you need a house.";
break;
default:
cout << "What are you? A peace-loving hippie freak?";
}
You can use like this:
case 4: case 2:
{
//code ...
}
For use 4 or 2 switch case.
Your example is as concise as it gets with the switch construct.
If you're willing to go the way of the preprocessor abuse, Boost.Preprocessor can help you.
#include <boost/preprocessor/seq/for_each.hpp>
#define CASE_case(ign, ign2, n) case n:
#define CASES(seq) \
BOOST_PP_SEQ_FOR_EACH(CASE_case, ~, seq)
CASES((1)(3)(15)(13))
Running this through gcc with -E -P to only run the preprocessor, the expansion of CASES gives:
case 1: case 3: case 15: case 13:
Note that this probably wouldn't pass a code review (wouldn't where I work!) so I recommend it be constrained to personal use.
It should also be possible to create a CASE_RANGE(1,5) macro to expand to
case 1: case 2: case 3: case 4: case 5:
for you as well.
gcc has a so-called "case range" extension:
http://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Case-Ranges.html#Case-Ranges
I used to use this when I was only using gcc. Not much to say about it really -- it does sort of what you want, though only for ranges of values.
The biggest problem with this is that only gcc supports it; this may or may not be a problem for you.
(I suspect that for your example an if statement would be a more natural fit.)
No, unless you want to break compatibility and your compiler supports it.
#include <stdio.h>
int n = 2;
int main()
{
switch(n)
{
case 0: goto _4;break;
case 1: goto _4;break;
case 2: goto _4;break;
case 3: goto _4;break;
case 4:
_4:
printf("Funny and easy!\n");
break;
default:
printf("Search on StackOverflow!\n");
break;
}
}