C++ Switch Statement - c++

Recently (yesterday hah) I started learning C++. I am trying to make a simple calculator to practice. I used a switch statement in order to call upon the correct method(or is it function.. don't know the nuances of c++...) within the class; However, the code will not compile because I am using a string to define which case to use and also defining multiple classes to have the same result.
Here is the switch statement (I've only done addition to squash any bugs before I add the others):
switch(input){
case 'A': case 'a': case 'add': case 'Add':
cout << bo.addNum();
break;
default:
cout << "Not addition";
break;
}
The error I'm getting is the following:
basic.cpp:41:2: error: statement requires expression of integer type ('string'
(aka 'basic_string<char, char_traits<char>, allocator<char> >') invalid)
switch(input){
^ ~~~~~
basic.cpp:42:28: warning: multi-character character constant [-Wmultichar]
case 'A': case 'a': case 'add': case 'Add':
^
basic.cpp:42:40: warning: multi-character character constant [-Wmultichar]
case 'A': case 'a': case 'add': case 'Add':
^
Here is the code in its totality:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class beckahClass{
public:
void setNum(int num1, int num2){
a = num1;
b = num2;
}
int addNum(){
return a + b;
}
int subNum(){
return a - b;
}
int divNum(){
return a / b;
}
int multNum(){
return a * b;
}
private:
int a, b;
};
int main (void){
beckahClass bo;
string input;
int a, b;
cout << "Please specify the operation to preform by the following:\n A: add\nS: subtract\nM: Multiple\nD: divide\nEnter operation: ";
cin >> input;
cout << "Enter the two nums you want to preform your operation on: ";
cin >> a >> b;
bo.setNum(a, b);
switch(input){
case 'A': case 'a': case 'add': case 'Add':
cout << bo.addNum();
break;
default:
cout << "Not addition";
break;
}
return 0;
}
I also realize there are probably more efficient ways to use logic; because I'm just starting C++, I would greatly appreciate any critique. I had been looking up 'maps' before briefly and was wondering if this might be a good instance to use it in?
Thanks.

The reason is that C/C++ switch statement takes an int argument and do not support string as a type. Although it supports the notion of constant array. Also to mention that C/C++ switch statements are typically generated as branch tables. and it is not easy to generate a branch table using a string style switch.
In C++ the switch statement takes int as the argument.
Why you cannot string in switch and getting the below error?
basic.cpp:42:28: warning: multi-character character constant [-Wmultichar]
case 'A': case 'a': case 'add': case 'Add':
^
basic.cpp:42:40: warning: multi-character character constant [-Wmultichar]
case 'A': case 'a': case 'add': case 'Add':
The reason is because to generate the code for switch the compiler must understand what it means for two values to be equal. For int and enum, it is trivial and easy as they are constant values. But when it comes to string then it is difficult resulting in error.

In C++, the switch statement takes an int argument, and you are trying to use it with a string, which you can not do in C++.
In this specific case, I'd argue that what you're trying to do with your switch is far to simple and an if else block would be better (plus it'd actually work with string).
For example:
if(input == "A" || input == "a" || input == "add" || input == "Add") {
cout << bo.addNum();
} else {
cout << "Not addition";
}
Alternatively, as others have explained, you can switch on a char. As it turns out, you can access the individual characters of a string quite nicely. This method will have your switch statement work on the first character of the string you took as input.
switch(input[0]) {
case 'A': case 'a':
//stuff
break;
case 'S': case 's':
//stuff
break;
//and so on
default:
//stuff
break;
}
Just keep in mind that if you do it this way, you're going to enter case 'A': case 'a': whether the user types A, a, add, Add, addition, Addition, ADD, or Apples, or alphabet, or anything that starts with an a.

welcome to the world of C++, hope you enjoy.
Anyway let's talk about your problem. Firstly, methods and functions are synonymous.
Secondly, the single quote is used around a single character and double quotes are used around a string.
As in I have a string "Rabbiya" that consists of characters 'R','a','b','i','y'. Get it?
So you write "add" and 'a' like that in the code. Get it?
Also in the switch statement, you are using two DIFFERENT data types to check the condition, one is a character and the other is a string. "add" and "Add" are strings and 'a' and 'A' are chars. Which is wrong. Cases have the values that the argument of the switch statement can or may take. And the argument will obviously be a variable of a particular type, we will get to that.
The data types of the CASES must be the same as that of the ARGUMENT of switch - statement. Here's one thing you can do, instead of keeping char or string, you ask the user to identify the operation they perform using a number instead. Like
int a = 0;
cout << Enter: 1 for Add\n2 for Sub\n3 for Div\n4 for Sub: ";
cin >> a;
Then u use switch(a) statement with cases : case:1, case:2 and so on.
Here it will be good to have a default case too so that if an invalid input is provided, it generates an error message.
One more thing, in the class, you have two data members namely a and b. You will need to initialize these too!
Otherwise you will get errors or garbage values depending on the compilers. For this purpose, you write class constructors. What are constructors? They help you initialize data members of a class object.
For this purpose you should refer to this link: http://www.learncpp.com/cpp-tutorial/85-constructors/
http://www.learncpp.com/ will help you a lot throughout your course!

string input;
try changing it to
char input

As it was said C++ does not support using user-defined types (std::string is a user defined type) in the switch statement. It allows to use only integral types or enumerations. By the way the type char belongs to integral types. If you want to use strings in the switch statement then write your program in C#.

You can use any type c/c++ switch implementation. Your code will be like this:
SWITCH(input)
CASE("A") FALL
CASE("a") FALL
CASE("Add") FALL
CASE("add") FALL
cout << bo.addNum();
BREAK
DEFAULT
cout << "Not addition";
END

Related

Why is declaring a variable in switch statement allowed? but not declaration + initialization?

Why is declaring + initializing a variable inside a case of a switch statement not allowed & gives an error, but if it is declared it on one line then assigned a value on another, it compiles?
Why the variable that was declared in a previous case can be used(operated on) in another matching case even if the previous case statements did not execute!
This code compiles with no errors or warnings:
char ch; cin>> ch;
switch(ch)
{
case 'a':
int x; // How come this is ok but not this(int x = 4;)?
x = 4;
cout<< x << endl;
break;
case 'b':
x += 1; // x is in scope but its declaration did not execute!
cout<< x << endl;
break;
case 'c':
x += 1;
cout<< x << endl;
break;
}
I expected case 'b' Or case 'c' to not know that there is a variable called x. I know the variable is still in scope in case b and case c.
case 'a' prints 4
case 'b' prints 1
case 'c' prints 1
Edit: No the other question thread that is marked as a possible duplicate does not answer my question.
why is the variable x can not be defined and initialized? what problems would that create that it is not allowed to do so?
If it is allowed to define the variable only in one statement, then the variable gets used in the matching case and whatever garbage was in there gets used; so what difference does it make from declare + initializing the value?
The case label functions as a target of a goto statement.
The C++ standard states in [stmt.dcl]/3:
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization.
So the below will fail:
case 'a':
int x = 4; //will fail
whereas the following will not fail:
case 'a':
int x; // this is ok
x = 4;
In response to the OP's edit:
In this particular case, just the declaration makes x visible throughout the switch statement as there are no braces {} surrounding it.
So x can be used in with the other cases as well although the compiler will warn about using it uninitialized. Note that reading of an uninitialized variable is undefined behavior.
To answer the last part of your question:
Suppose the declaration with initialization was allowed it would mean that that particular value of x (4 in this case) would have to be used in other cases as well.
Then it would seem as if code for multiple cases was executed. So this is not allowed.

Expression Syntax in Function Error Help! C/C++

Please help with my switch case I'm not sure on how I'm meant to put my functions in the cases. Do I keep the parameters in?
void ChoiceConvert(char unit){
char c, f;
printf("Enter your choice for converting from Kelvin\n1. 'c' to convert to Celcius\n2. 'f' to convert to Farenheit");
switch(unit)
{
case 'c':
ConvertCel(int temp, const int Freeze);
break;
case 'f':
ConvertFar(int temp, const int Freeze);
break;
default:
printf("\n");
}
return;}
This is the error I am getting.
Error E2188 state.cpp 53: Expression syntax in function ChoiceConvert(char)
Error E2188 state.cpp 56: Expression syntax in function ChoiceConvert(char)
There's a few issues with your code.
First: this function is meant to convert a temperature- you pass the char unit that you want it converted to- either C or F. SO
char c, f;
printf("Enter your choice for converting from Kelvin\n1. 'c' to convert to
Celcius\n2. 'f' to convert to Farenheit");
shouldn't be inside the function at all - it should be asked previous to the function, and then the answer is passed into ChoiceConvert.
Second: there's no temperature here. I assume you should ask the user that in main() as well, and pass that in as an argument as well as the unit.
Third: As stated by others, you're writing the function parameters, not its arguments. You should have the parameters (ie. the function declaration & definition) outside of this function, and then you CALL it within this function. Check this out in order to learn the difference between declarations, definitions, and calling. It's pretty vital base knowledge for programming.
Here's how I would do it:
int main()
{
char conversion;
int temperature;
printf("Enter your choice for converting from Kelvin\n1. 'c' to convert to Celcius\n2. 'f' to convert to Fahrenheit");
std::cin >> conversion; // requires #include <iostream>
printf("Enter the temperature you wish to convert:");
std::cin >> temperature; // requires #include <iostream>
ChoiceConvert(temperature, conversion); // calling the function
}
void ChoiceConvert(double temp, char unit)
{
switch(unit)
{
case 'c':
ConvertCel(temp);
break;
case 'f':
ConvertFar(temp);
break;
default:
printf("\n");
}
}
void ConvertCel(double temp)
{
// conversion here
}
void ConvertFar(double temp)
{
// conversion here
}
Also, UI side note- be careful: if you're looking for the user to input characters, making it a numbered list can be confusing.
When you are calling your conversion functions you are using their declaration instead of passing them actual values.
This is one of the offending lines:
ConvertFar(int temp, const int Freeze);
ConvertCel(int temp, const int Freeze);
You placed function signature instead of a statement. Twice.

C++ make a variable type depend on user input

I want a function that creates an array for testing purposes:
The idea es to make the user select the type of elements the array will contain (int, float, double).
Then it has to return an array of the selected type and main has to use it as a parameter. I understand this is done using a void pointer, but I would be glad if someone could provide me an example.
So this would be the example code
**type** vector()
{
int t;
int op;
cout << "Size: \n";
cin >> t;
**type** * v = new **type**[t]
cout << "Select type\n";
cin >> op;
switch(op) {
case 0:
// Create the array with the selected option...
return * v;
case 1:
// Create the array with the selected option...
return * v;
default:
// Other stuff;
}
}
So the question would be what type of function should I use, and also what type of dynamic variable should I declare as v.
And also how to use it later on other functions once correctly done.
Thanks.
The simple answer is that you cannot, because data types need to be specifically declared at compile time.
If you can use boost libraries,
boost::variant<int,float,double> vec;
can suit your needs.
You cannot use union because std::vector is not a POD (Plain Old Datatype).
EDIT:
As #Rob pointed out:
Void pointers need to be converted into a pointer to something else -
at compile time - before they can be used that way. So the answer is
still "cannot" use void pointers to make a variable data type.
Since C++ is a statically typed language, you cannot really do this in a simple way. You cannot determine types at runtime, these are fixed as soon your program has been compiled.
The closest thing you can get for your case IMHO, is using something like a boost::variant or boost::any.
I think you should re-think your design.
Rather than trying to write a function that returns an array of user-defined type to test. I would instead call a different test function depending on the user choice.
The test function can be templated to avoid code duplication:
#include <vector>
#include <iostream>
template<typename T>
void doTest(unsigned size) {
std::vector<T> data(size);
// Do the actual test on the data...
}
int main() {
unsigned size;
std::cout << "Size: \n";
std::cin >> size;
int op;
std::cout << "Select type\n";
std::cin >> op;
switch(op) {
case 0:
doTest<int>(size);
break;
case 1:
default:
doTest<float>(size);
}
}
If you really want to return your array from a function you could wrap it in a polymorphic type. But to actually do anything with the array you would need to call a virtual method on the polymorphic type so I don't see how it buys you anything over calling a test function directly.
it can be done using void* but in that case you need to do type casting yourself (as pointed out by #Rob) i.e. using reinterpret_cast operator or similar. Here is a simple example with void*
void* vector(){
int t;
int op;
cout << "Size: \n";
cin >> t;
cout << "Select type\n";
cin >> op;
switch(op) {
case 0:
// Create the array with the selected option...
return reinterpret_cast<void*>(new int[t]);
case 1:
// Create the array with the selected option...
return reinterpret_cast<void*>(new double[t]);
default:
// Other stuff;
return reinterpret_cast<void*>(new float[t]);
}
}
Note: you can look at working of malloc() function, it always returns void* to allocated memory and you have to type cast it yourself e.g malloc(sizeof(int)*t)

user select array type from menu c++

I have created a generic array-like template to create arrays of different types. Now I need to get user input from a menu about which type of array they are building. I tried having the user enter a number and using that number to pick a string from an array of constant strings. But pretty obviously, that threw a type conversion error. Is there a way to convert the literal string of a type into it's type or refer to a type directly. Thanks!
Here is the code I need to fit a type into at runtime:
SimpleVector<TYPE> myVect = SimpleVector<TYPE>(dataSize);
I also tried this switch statement which I would like better but I am getting a redefinition error.
switch (dataChoice) {
case 1:
SimpleVector<int> myVect = SimpleVector<int>(dataSize);
break;
case 2:
SimpleVector<double> myVect = SimpleVector<double>(dataSize);
break;
case 3:
SimpleVector<string> myVect = SimpleVector<string>(dataSize);
break;
default:
break;
}
To get rid of the redefinition error you have to enclose the type definition inside curly brackets
switch (dataChoice) {
case 1:
{
SimpleVector<int> myVect = SimpleVector<int>(dataSize);
break;
}
case 2:
{
SimpleVector<double> myVect = SimpleVector<double>(dataSize);
break;
}
default:
break;
}
TYPE is something the compiler has to know at compilation time: when you try to use a string value instead of a type the compiler will refuse to collaborate.
Refer to What does template <unsigned int N> mean?

c++ switch case

whenever I try to use switch with
case myvar:
where myvar is a char I get an error. Is it possible to make it work? Thanks
The expressions used in cases must be constant integral expressions that can be evaluated at compile time. So no. Unless myvar is a static const int of some sort, you can't make this work using case.
But what you can do is just use chained if statements.
In general, no. Cases must be compile-time constants.
It seems you want your switch cases to work based on char. As others said, your switch cases should be integral compile-time constants. And the below example works because, the corresponding ASCII values are retrieved for each case of char.
#include <iostream>
int main( void )
{
char myvar = 'a' ;
switch( myvar )
{
case 'a':
std::cout << "\n This Works !" << std::endl ;
break ;
default:
break ;
}
return 0 ;
}
Hope this helps !