if statement doesn't work in the block of switch? - c++

I wrote a simple function as the following, but it does not work as expected, in C++, the if statement doesn't work in the block of switch?
void any2ten(string origin, int type)
{
if(! (type == 2 || type == 8 || type == 16))
{
cout << "unsupport this " << endl;
return;
}
int result = 0;
for (int index = 0; index < origin.length(); index++)
{
int tmp = 0;
switch (origin[index])
{
if (type == 16)
{
case 'F':
case 'f':
tmp = 15 * pow(type, index); break;
case 'E':
case 'e':
tmp = 14 * pow(type, index); break;
case 'D':
case 'd':
tmp = 13 * pow(type, index); break;
case 'C':
case 'c':
tmp = 12 * pow(type, index); break;
case 'B':
case 'b':
tmp = 11 * pow(type, index); break;
case 'A':
case 'a':
tmp = 10 * pow(type, index); break;
case '9':
tmp = 9 * pow(type, index); break;
case '8':
tmp = 8 * pow(type, index); break;
}
if (type == 8 || type == 16)
{
case '7':
tmp = 7 * pow(type, index); break;
case '6':
tmp = 6 * pow(type, index); break;
case '5':
tmp = 5 * pow(type, index); break;
case '4':
tmp = 4 * pow(type, index); break;
case '3':
tmp = 3 * pow(type, index); break;
case '2':
tmp = 2 * pow(type, index); break;
}
case '1':
tmp = 1 * pow(type, index); break;
case '0':
tmp = 0; break;
default:
cout << "wrong character has got" << endl;
return;
break;
}
result += tmp;
}
cout << result << endl;
}
while I test the function as any2ten("aa", 8), the result is 90 rather than wrong character.
is there anything wrong?

The if statement works fine in the block of a switch, you've just put it in a place where it never gets executed. The switch statement jumps to the corresponding case, that is its purpose. Whatever it jumps to, it will skip over the if, so the if never executes.
If you were to add code to make it possible to jump to between the switch and the if, then the if would execute normally. You could do this with a loop of any kind or a goto.
A default is only taken if no case is matched. Otherwise, the switch jumps to the matching case.

The switch statement doesn't work the way you imagine that it works. The way it behaves is not as a substitute of an if-else if-else, but somewhat differently.
Upon encountering the switch the process will jump to the code following the correct case. This means that you actually completely skip the execution of the if that you have placed there.
And yes, it does look weird, since you assume that because you have the curly braces you must execute if condition or not enter into them at all, but this is simply not the case.

Well the placement of your if-statement doesn't really make sense. The switch-statement jumps to the corresponding case and then exists, hence your if-statement won't be executed. And I wouldn't recommend to use goto, cause it's considered as a bad-practice.

Related

Switch Statement with multi-dimensional array

I have the following switch statement that actually works fine.
for (n = 0; n < 10; n++){
switch(results[r][n]){
case 0:
result[r][n] = "FAIL";
break;
case 1:
result[r][n] = "PASS";
break;
default:
break;
}
}
my question is WHY does this work, is it supposed to work or is there a much better way of doing this?
Is this how you are supposed to implement multi-dimensional arrays within a switch?
(r = 0 or 1)
How does the compiler know whether case 0: refers to r or n?
case 0 refers to results[r][n], not r or n. The values after case are matched to the value of the expression in the switch().
Look at a tutorial on switch-case
Your switch statement
switch(results[r][n]) {
case 0:
result[r][n] = "FAIL";
break;
case 1:
result[r][n] = "PASS";
break;
default:
break;
}
is equivalent to:
if (results[r][n] == 0)
result[r][n] = "FAIL";
else if (results[r][n] == 1)
result[r][n] = "PASS";
else
// do nothing
To anyone who was confused by the assignment of a string to something that should be an integer array, results is the integer[] array, result is a different variable that's a string[] array. As Robert notes below in the comments, a better naming system seems to be in order here.

Can anyone explain this function definition above the switch statement?

Here, I've made a function, that takes a character array and a single element array as input.
The input of expression is like "56+78", and then someone suggested this approach of using ascii code and for loops to store the two "numeric" substrings as two numbers, and used the character and switch statement below. But, I don't understand the part of storing these substrings as numbers and the asciicode concept.
void calculate(char ch[], char op[]){
int i;
int num1 = 0, num2 = 0;
for(i=0; ch[i]!='\0';i++)
{
if((int)ch[i]>=48 && (int)ch[i]<=57){
num1 = num1*10+(((int)ch[i])-48);
}
else{
op[0]=ch[i];
break;
}}
i++;
for(; ch[i]!='\0';i++)
{
if((int)ch[i] >= 48 && (int)ch[i] <= 57){
num2 = num2*10+(((int)ch[i])-48);
}
}
cout<<"OUTPUT: ";
switch(op[0])
{
case '+':
cout<<num1 + num2<<endl;
break;
case '-':
cout<<num1 - num2<<endl;
break;
case '*':
cout<<num1 * num2<<endl;
break;
case '/':
cout<<num1 / num2<<endl;
break;
}
}

How to convert char into int in a function?

poziomy= char;
pionowy= digit; ( no problems with this one)
So I need to convert char into a digit in function but obviusly I cannot do char=int, so I dont know how to pass on the converted char into digit properly.
I guees i can do two functions but maybe there is an easier way?
I thought of making a new variable poziomy_c but I dont know how to pass it to Ruch_gracza()
int Convert_digit (int cyfra)
{
switch (cyfra)
{
case 10: return 0;break;
case 9: return 1;break;
case 8: return 2;break;
case 7: return 3;break;
case 6: return 4;break;
case 5: return 5;break;
case 4: return 6;break;
case 3: return 7;break;
case 2: return 8;break;
case 1: return 9;break;
}
}
int Convert_letter (char literka)
{
switch (literka)
{
case 'A': return 0; break;
case 'B': return 1; break;
case 'C': return 2; break;
case 'D': return 3; break;
case 'E': return 4; break;
case 'F': return 5; break;
case 'G': return 6; break;
case 'H': return 7; break;
case 'I': return 8; break;
case 'J': return 9; break;
}
}
void Conwert(int &pionowy, char poziomy)
{
pionowy=Convert_digit(pionowy);
int poziomy_c;
poziomy_c=Convert_letter (poziomy);
}
void Ruch_gracza1 (int plansza[10][10])
{
int pionowy ;
char poziomy;
cout << "wprowadz wspolrzedne pola na ktorym lezy pion który chcesz ruszyc ( w pionie , potem w poziomie)" << endl;
cin >> pionowy >> poziomy;
Conwert (pionowy,poziomy);
cout << pionowy << endl;
cout << poziomy << endl;
}
You can use char arithmetic to make this a whole lot easier. Since 'A' to 'Z' will be contiguous in ASCII/Unicode, you can do literka - 'A' to get how far literka is from A (which is what your switch is doing):
int Convert_letter (char literka) {
if(!std::isalpha(literka)) { return literka; } // Not a letter
return std::toupper(literka) - 'A';
}
Or if you want a more robust solution to cover even less common character encodings:
int Convert_letter (char literka) {
if(!std::isalpha(literka)) { return literka; } // Not a letter
std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
return std::distance(std::begin(alphabet), std::find(std::begin(alphabet), std::end(alphabet), literka));;
}
Convert_digit will look similar (except with std::isdigit instead of std::isalpha).
You can do as
char c = 'B';
int digit = c - 'A';
return digit;
You need some knowledge about the ASCII table and data type in C++.
Simply, a char is an integer from -128 ... 127. If you declare a char variable name ch like this:
char ch = 'B';
C++ will understand that ch = 66 (look at ASCII table). So that we can do arithmetic operator with ch like an integer variable.
ch - 'A'; // result 1, because 'A' = 65
ch - 65; // same result with ch - 'A'
Finally, you can write your function like this:
int functionChar2Int(char x){
return x - 'A';
}

How to read data from file into an array

I have this program to take properties from a data file and input them into calculations into the program. this is my code at the moment but it isn't taking any values into it.. any help is appreciated
float woodcharacStrength(){
myInfile.open ("strength_classes.txt"); //inputs external file that contains characteristic values for forces parallel to grain.
for (row = 0; row<3; row++)
for (col = 0; col<18; col++) //condition to only read certain rows and columns of the input file
{
myInfile >> arraylocation[row][col]; //used to define each value of the array
}
switch(woodType){
case 'A':
case 'a': ftk = arraylocation[0][0]; fck = arraylocation[1][0];break;
case 'B':
case 'b': ftk = arraylocation[0][1]; fck = arraylocation[1][1];break;
case 'C':
case 'c': ftk = arraylocation[0][2]; fck = arraylocation[1][2];break;
case 'D':
case 'd': ftk = arraylocation[0][3]; fck = arraylocation[1][3];break;
case 'E':
case 'e': ftk = arraylocation[0][4]; fck = arraylocation[1][4];break;
case 'F':
case 'f': ftk = arraylocation[0][5]; fck = arraylocation[1][5];break;
case 'G':
case 'g': ftk = arraylocation[0][6]; fck = arraylocation[1][6];break;
case 'H':
case 'h': ftk = arraylocation[0][7]; fck = arraylocation[1][7];break;
case 'I':
case 'i': ftk = arraylocation[0][8]; fck = arraylocation[1][8];break;
case 'J':
case 'j': ftk = arraylocation[0][9]; fck = arraylocation[1][9];break;
case 'K':
case 'k': ftk = arraylocation[0][10]; fck = arraylocation[1][10];break;
case 'L':
case 'l': ftk = arraylocation[0][11]; fck = arraylocation[1][11];break;
case 'M':
case 'm': ftk = arraylocation[0][12]; fck = arraylocation[1][12];break;
case 'N':
case 'n': ftk = arraylocation[0][13]; fck = arraylocation[1][13];break;
case 'O':
case 'o': ftk = arraylocation[0][14]; fck = arraylocation[1][14];break;
case 'P':
case 'p': ftk = arraylocation[0][15]; fck = arraylocation[1][15];break;
case 'Q':
case 'q': ftk = arraylocation[0][16]; fck = arraylocation[1][16];break;
case 'R':
case 'r': ftk = arraylocation[0][17]; fck = arraylocation[1][17];break;
}
cout <<"The ftk value is: "<< ftk<< endl<<"The fck value is: "<< fck<<endl;
return ftk;
return fck;
myInfile.close();
}
for (row = 0; row<3; row++) //you have no open and close braces for this for loop
Suggestions:
1) Look up std::toupper or std::tolower so you don't have to use both upper and lower case letters in your case statements.
2) Create a index by subtracting letters:
unsigned int index = std::toupper(woodType) - 'A';
ftk = arraylocation[0][index];
fck = arraylocation[1][index];
3) A function can only return one value: ftk or fck.
If you want to return more than one value, pass them by reference or put them in a structure and return a copy of the modified structure.
4) No execution flows after a return statement, so your code will never execute the 2nd return statement or the fclose.

can not convert parameter 1 from int into &int

Lets imagine I have got functions:
int switcherINT(char &c){
switch (c){
case '1': return 1; break;
case '2': return 2; break;
case '3': return 3; break;
case '4': return 4; break;
case '5': return 5; break;
case '6': return 6; break;
case '7': return 7; break;
case '8': return 8; break;
case '9': return 9; break;
case '0': return 0; break;
default: return err;
}
}
char switcherCHAR(int &c){
switch (c){
case 1: return '1'; break;
case 2: return '2'; break;
case 3: return '3'; break;
case 4: return '4'; break;
case 5: return '5'; break;
case 6: return '6'; break;
case 7: return '7'; break;
case 8: return '8'; break;
case 9: return '9'; break;
case 0: return '0'; break;
default: return errCH;
}
}
and I am trying to compute nest expression:
c.str[i] = switcherCHAR(switcherINT(pthis->str[pthis->size-i-1])-switcherINT(pb->str[pb->size-i-1])-loc);
where
longMath *pthis(this),*pb(&b);
longMath c;
class longMath{
protected:
char* str;
int size;
protected:
........
compiler says:
"can not convert parameter 1 from int into &int"
Haw can I solve this problem?
The expression that you've given as an argument to switcherCHAR gives you a temporary int. You cannot pass a temporary as a reference - unless you make the reference const. Just change switcherCHAR to take a const int& (and while you're at it, make switcherINT take a const char&). However, this are very simple types and you're probably better off just taking them by value. So change them to take just int and char.
Nonetheless, your functions are pretty strange. It is very easy to convert between a number x and it's char counterpart just by doing '0' + x. The numerical digit characters are guaranteed to be in consecutive order. So if you take the value of '0' and add, lets say, 5, you will get the value of the character '5'.
It would be much better to use functions like this:
int switcherINT(const char &c) {
return (c >= '0' && c <= '9') ? c - '0' : err;
}
char switcherCHAR(const int &c) {
return (c >= 0 && c <= 9) ? '0' + c : errCH;
}