An if statement within a switch statement? - c++

I'm having difficulties seeing why one way works and way doesn't.
I have;
switch (key)
{
//If Game over Label is visible, enable the m and e buttons
if(mGameOverLabel->GetVisible())
{
case 'm': case 'M':
ResetScreen();
break;
case 'e': case 'E':
// //Exit the game
Stop();
break;
} else {
case ' ':
mSpaceship->Shoot();
break;
default:
break;
}
For the case of the m and e, even though mGameOverLabel is set to false at this current time, I can still press M and E and these will react according to the methods, but If I change it to this for M it will then only work when I need it too. Am I missing something here?!
switch (key)
{
//If Game over Label is visible, enable the m and e buttons
case 'm': case 'M':
if(mGameOverLabel->GetVisible()) ResetScreen();
break;
}

The switch basically does a goto to the appropriate case label. Any logic above the case will not be executed.

Related

What characters should I encode always?

Trying to encode the URL before the HTTP call but getting no response from the server (response code 0). Without encoding things working fine.
Requirement:
Need to encode special characters in URL. Specifically, I need to encode the below characters plus any other such characters:
! * ' ( ) ; : # & = + $ , / ? % # [ ]
This is my understanding of Url Encoding:
Only alphanumeric and a few special characters ("-", ".", "_", "~")  may be used unencoded within a URL. The rest of the characters transmitted as part of the URL, whether in the query string or path segment, must always be encoded. Reference.
I am doubtful on "*", as in Android this can also go unencoded. Reference
I tried encoding the whole URL, as well as individual params, but I'm getting the same result.
Below is my encoding function:
void Url::escape(String& str)
{
if(str.isEmpty())
{
return;
}
uint32_t i = 0;
unsigned char in;
char hexbuf[4];
while(i < str.size())
{
in = static_cast<unsigned char>(str[i]);
switch(in)
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': case '~': case '.': case '-':
break;
default:
str[i] = '%';
snprintf(hexbuf, 3, "%02X", in);
str.insert(hexbuf, i + 1);
i += 2;
break;
}
++i;
}
}
Am I missing anything here? I want clarity on below as well:
Can I call Url::escape() on the whole input url String, or should I encode individual query params only?
What characters can/should I omit in encoding (is Url::escape() correct or not)?
I referred to multiple references here, but I could not find any concrete solution.
Can I call Url::escape() on whole input url String or should I go by encoding indivisual query param only?
You must encode individual components of the url, not just the query params.
What characters I can/should omit in encoding (is Url::escape() is correct or not)?
Different components have different rules of what characters need to be encoded and which ones do not.
RFC 3986: Uniform Resource Identifier (URI): Generic Syntax outlines the basic rules that all URLs have to conform to. However, there are lots of URL schemes, many of which provide additional rules/restrictions on top of this syntax for scheme-specific components, and have their own RFCs.

Error: break statement not within loop or switch

I wrote this part of code and a series of error are being shown. The above mentioned error being the first. What is wrong in the code?
void direction(char ch)
{
switch(ch)
case 'w': if(dirn!=3){dirn=1;}
break;
case 'a': if(dirn!=2){dirn=4;}
break;
case 's': if(dirn!=1){dirn=3;}
break;
case 'd': if(dirn!=4){dirn=2;}
break;
You can choose to omit the opening and closing braces for a switch statement only when you have only one case in your switch block as shown below:
void direction(char ch)
{
switch(ch)
case 'w': if(dirn!=3){dirn=1;}
}
But, if you have got multiple cases to deal with like in your case then you must enclose them inside a pair of opening and closing braces to create a code block for the switch statement as shown below:
void direction(char ch)
{
switch(ch)
{//opening brace for starting of statement block
case 'w': if(dirn!=3){dirn=1;}
break;
case 'a': if(dirn!=2){dirn=4;}
break;
case 's': if(dirn!=1){dirn=3;}
break;
case 'd': if(dirn!=4){dirn=2;}
break;
}//closing brace for closing of statement block
So you will have to either remove all the cases but one OR add the pair of braces to create statement block. In all other cases your code won't compile successfully.
You have forgotten the switch braces :
void direction(char ch)
{
switch(ch)
{
case 'w': if(dirn!=3){dirn=1;}
break;
case 'a': if(dirn!=2){dirn=4;}
break;
case 's': if(dirn!=1){dirn=3;}
break;
case 'd': if(dirn!=4){dirn=2;}
break;
}
}
switch statement requires braces block, where all labels including default one should be:
switch(ch)
{
case 'w': if(dirn!=3) dirn=1;
break;
case 'a': if(dirn!=2) dirn=4;
break;
case 's': if(dirn!=1) dirn=3;
break;
case 'd': if(dirn!=4) dirn=2;
break;
default:
break;
}
The statement after switch must be a compound statement to contain case, default and break. Break got a special meaning here, different from loops. If brace was omitted only next line after switch is part of its statement.

Using getchar() function

I used getchar() to stop the while string. My problem is that it does stop the while string if I type one or two characters, if the user input is more the two characters nothing happens.
here is the code:
printf("enter srting\n");
while ((tmp=getchar()) !='\n') { \\here is my problem
count_letters++;
/* COUNTING WORD THAT START WITH LETTES L,A,C,H */
while (count_letters%3==0) {
switch (tmp) {
case 'A': count_a++;
break;
case 'C': count_c++;
break;
case 'H': count_h++;
break;
case 'L': count_l++;
default:
break;
}
} /* end of count letters while */
n1=n2;
n2=n3;
n3=tmp;
if (n1=='H' && n2=='Y' && n3=='A') {
count_hya++;
}
} /* end of getchar while */
printf("\n");
printf("%d", count_letters);
I believe it's your code :
"while (count_letters%3==0))"
is something wrong!
because when you type more than three letters,your variable "count_letters" will add to 3 due to the code:"count_letters++;".
May be you could change the "while" to "if" and see if it's working correctly~
Here's the problem:
while (count_letters%3==0) {
switch (tmp) {
case 'A': count_a++;
break;
case 'C': count_c++;
break;
case 'H': count_h++;
break;
case 'L': count_l++;
default:
break;
}
}
when your the third character is read, your program enters a infinite loop because of (count_letters%3==0)
I can't understand the purpose of your code.
I suggest using gets() and string manipulation functions because you are processing an entire line. (see string.h)
getchar() is also less efficient compared with gets() + for-loop

c++ classes switch case

switch(choice)
{
case 1:
uinstance1.addNewProduct(data);
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
uinstance1.listAllProducts(data);
break;
case 8:
break;
case 9:
break;
case 10:
//name,category,barcode,price,manufacturer,noinstock,soldpermonth,expirydate,discount
// Perishable(string,string,string,double,string,int,int);
Perishable item0("Ferrari","Automobile","9999",2999.99,"Popular",5,0);
data.addNew(item0);
break;
default:
cout<<"Wrong Choice "<<endl;
system("pause");
break;
}
}
Hi ,i have been thinking about this error for quite some time and cant seem to figure out the issue.
error C2361: initialization of 'item0' is skipped by 'default' label
: see declaration of 'item0'
Some help would be appreciated.
Thanks
The whole select block counts as one scope, if you decalare a variable in that scope you need to initialize it in every case statement (every possible execution path). You can avoid it by creating a additional scope in your case to avoid the problem (see the brackets):
switch(choice)
{
case 1:
uinstance1.addNewProduct(data);
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
uinstance1.listAllProducts(data);
break;
case 8:
break;
case 9:
break;
case 10:
{
//name,category,barcode,price,manufacturer,noinstock,soldpermonth,expirydate,discount
// Perishable(string,string,string,double,string,int,int);
Perishable item0("Ferrari","Automobile","9999",2999.99,"Popular",5,0);
data.addNew(item0);
}
break;
default:
cout<<"Wrong Choice "<<endl;
system("pause");
break;
}
}
MSDN explains the error C2361 aptly:
The initialization of identifier can be skipped in a switch statement. You cannot jump past a declaration with an initializer unless the declaration is enclosed in a block. (Unless it is declared within a block, the variable is within scope until the end of the switch statement.)
Always pay attention to the error numbers they provide vital information about why the error.
You forgot the braces in one of the cases.
case 10:
{
^^^
Perishable item0;
data.addNew(item0);
break;
}
^^^
Your label is crossing initialization which is illegal. Pretty sure moving default to the top should fix it. You can also add code blocks { } around your relevant code. If you still have problems then move your object outside of the switch block.
You can't create variables inside case statements if you don't define explicity the scope.
There is another discussion about that: Variables inside case statement
case 10:
{ // <<-- This gives explicit scope for the stack variable and let's you get rid of the error
Perishable item0;
// ...
}
break;

simple cross-platform c++ GUI console -- how to?

I'm writing a game and I'm wound up in needing a console for simple text input; filenames and simple values.
Using SDL, my console looks the following at it's simplest:
class Console
{
public:
typedef std::list<String> InputList;
enum Result
{
NOTHING = 0,
ENTERED,
ESCAPED
};
static const String& GetInput() { return input; }
static Result Query(SDLKey lastKey)
{
if(lastResult == ENTERED || lastResult == ESCAPED)
{
input.clear();
}
switch (lastKey)
{
case SDLK_a:
case SDLK_b:
case SDLK_c:
case SDLK_d:
case SDLK_e:
case SDLK_f:
case SDLK_g:
case SDLK_h:
case SDLK_i:
case SDLK_j:
case SDLK_k:
case SDLK_l:
case SDLK_m:
case SDLK_n:
case SDLK_o:
case SDLK_p:
case SDLK_q:
case SDLK_r:
case SDLK_s:
case SDLK_t:
case SDLK_u:
case SDLK_v:
case SDLK_w:
case SDLK_x:
case SDLK_y:
case SDLK_z:
case SDLK_0:
case SDLK_1:
case SDLK_2:
case SDLK_3:
case SDLK_4:
case SDLK_5:
case SDLK_6:
case SDLK_7:
case SDLK_8:
case SDLK_9:
case SDLK_SLASH:
case SDLK_BACKSLASH:
case SDLK_PERIOD:
case SDLK_COMMA:
case SDLK_SPACE:
case SDLK_UNDERSCORE:
case SDLK_MINUS:
input += static_cast<char> (lastKey);
lastResult = NOTHING;
break;
case SDLK_RETURN:
lastResult = ENTERED;
break;
case SDLK_ESCAPE:
lastResult = ESCAPED;
break;
}
return lastResult;
}
protected:
static Result lastResult;
static String input;
};
This would be called from the application's main event loop, if the console is active and the last event was a keypress, then the result of the input is processed at a state where it's necessary.
Of course, it looks incredibly awkward... What's a better way to implement a simple console that can be easily rendered in my game's window? (Not going anywhere near to highly unportable solutions like having to reroute std::cout or writing code to bring up a UNIX console etc.)
One suggestion I would offer is to use if statements instead of a switch in this case:
if(lastKey == SDLK_RETURN)
lastResult = ENTERED;
else if(lastKey == SDLK_ESCAPE)
lastResult = ESCAPED;
else if(lastKey >= SDLK_SPACE && lastKey <= SDLK_z)
{
input += static_cast<char> (lastKey);
lastResult = NOTHING;
}
I took some liberties and included some characters that you didn't have in your code above, such as the ampersand, quotes, parentheses, brackets, etc. If you don't want those keys, you can add a few more if statements to break it down a bit more.
This assumes that the enum for the keys doesn't change a lot. If it does change a lot you may be better off with what you had.