c error: case label does not reduce to an integer constant - c

This is the switch case concerned by the error:
switch(event.type)
{
case SDL_Quit:
for (int i=0;i<NUMMENU;i++)
SDL_FreeSurface(menus[i]);
return 1;
case SDL_MOUSEMOTION:
x=event.motion.x;
y=event.motion.y;
for(int i=0;i<NUMMENU;i++)
{
if(x>=position[i].x && x<=position[i].x+position[i].w && y>=position[i].y && y<=position[i].y+position[i].h)
{
if(!selected[i])
{
selected[i]=1;
SDL_FreeSurface(menus[i]);
menus[i]=TTF_RenderText_Solid(font,labels[i],color[1]);
}
}else{
if(selected[i])
{
selected[i]=0;
SDL_FreeSurface(menus[i]);
menus[i]=TTF_RenderText_Solid(font,labels[i],color[0]);
}
}
}
case SDL_MOUSEBUTTONDOWN:
x=event.button.x;
y=event.button.y;
for(int i=0;i<NUMMENU;i++)
if(x>=position[1].x && x<=position[1].x+position[i].w && y>=position[i].y && y<=position[i].y+position[i].h)
{
for(int j=0;j<NUMMENU;j++)
SDL_FreeSurface(menus[j]);
return i;
}
break;
case SDL_KEYDOWN:
if(event.key.keysym.sym==SDLK_ESCAPE)
{
for(int i=0;i<NUMMENU;i++)
SDL_FreeSurface(menus[i]);
return 0;
}
}
I have this error and I haven't any idea of why and what should I do to resolve this. I have tried to add break; at the end of each case but no results.
If you need more code or further information, I can give precisions.
Regards,

You are using the function void SDL_Quit(void) rather than the SDL_QUIT event type at line 3.
case SDL_Quit:
^^^^^^^^
for (int i=0;i<NUMMENU;i++)
SDL_FreeSurface(menus[i]);
return 1;

Your case labels such as SDL_Quit/SDL_MOUSEMOTION... could not be integer constants. For example its valid if they are characters labels but not something like const char * string literals which are not integer constants.

Related

finite state machine for reading password

I'm trying to read the input from a user using keypad 4x4 and compare the input using a finite state machine as shown below.
When I come to case fourth my state machine does not go to Check case but to the default instead and then takes a key to go to CHECK immediately which makes the user press five times instead of 4.
while (1)
{
key=get_key();
if (key>=0 && key <=9){
switch (password){
case FIRST:
if (key==7 && i==0)
{
temp++; // increasing every time we enter correct number
password=SECOND;
HAL_Delay(300);
break;
}
HAL_Delay(300);
i++; // To check if we have fed in wrong digit
if(i==4) {
password=CHECK;
}
break;
//**********************************************************************************************************
case SECOND:
if (key==3 && temp==1){
temp++;
HAL_Delay(300);
password=THIRD;
break;
}
HAL_Delay(300);
i++;
if((i==3) || (i==2)) {
password=CHECK;
}
break;
//****************************************************************************************************
case THIRD:
if (key==9 && temp==2)
{
temp++;
HAL_Delay(300);
password = FOURTH;
break;
}
HAL_Delay(300);
i++;
if((i==2) || (i==1)) {
password=CHECK;
}
break;
//*******************************************************************************************************
case FOURTH:
if (key==2 && temp==3)
{
temp++;
password=CHECK;
break;
}
//HAL_Delay(300);
i++;
if(i==1) {
password=CHECK;
}
break;
//****************************************************************************************************
case CHECK:
if (temp==4){ // if temp has incresed to 4 that means that all the numbers entered are correct
HAL_GPIO_WritePin(Led_test_GPIO_Port,Led_test_Pin,1);
HAL_GPIO_WritePin(Led2_test_GPIO_Port,Led2_test_Pin,0);
password=IDLE_PASSWORD;
}
else if((i==4) || (i==3) || (i==2) || (i==1)) {
HAL_GPIO_WritePin(Led2_test_GPIO_Port,Led2_test_Pin,1);
HAL_GPIO_WritePin(Led_test_GPIO_Port,Led_test_Pin,0);
password=IDLE_PASSWORD;
}
break;
//******************************************************************************************************
case IDLE_PASSWORD:
temp=0;
i=0;
password = FIRST;
break;
default:
password = FIRST;
break;
}
}
}
while (1)
{
static uint8 Password[4] = {7, 3, 9, 2};
static uint8 Guesses = 0;
static uint8 Wrong = 0;
/*Get the key*/
key=get_key();
/*If the key is not in range...*/
if (key<0 || key >9)
{
/*Return early*/
return;
}
/*Wait 300*/
HAL_Delay(300);
/*If the value at the Guess position is not equal to what they pressed...*/
if (key != Password[Guesses])
{
/*Mark the input as wrong*/
Wrong = 1
}
/*Increment Guesses for the next time*/
Guesses++;
/*After their fourth input...*/
if (Guesses == 4)
{
/*Reet Guesses*/
Guesses = 0;
/*If they were wrong...*/
if (Wrong == 1)
{
/*Reset Wrong*/
Wrong = 0;
}
/*Otherwise if they were right...*/
else
{
/*Do something*/
}
}
}
This is untested - debug a bit and it should work.

C error C2660: 'Menu' : function does not take 3 arguments

I am new to programming and do not understand this error.
I have the same arguments in the Menu () function and when I call the same function in the menu_principal () function.
In function menu_principal(), I want execute the switch-case statement by the function Menu() with 'option' variable.
Can you help please?
int main()
{
void menu_principal();
return 0;
}
void menu_principal()
{
bool stop = true;
int option;
const char *title = "MENU PRINCIPAL";
const char *options_menu[] = { "ARTIGOS", "CLIENTES", "ORCAMENTOS", "SAIR" };
int n_options = 4;
do
{
option = Menu(title, options_menu, n_options);
switch (option)
{
case 1:
Menu_Item();
break;
case 2:
Menu_Client();
break;
case 3:
Menu_Billing();
break;
case 4:
stop = false;
break;
}
} while (stop);
}
int Menu(const char *title1, const char *options_menu1[], int n_options1)
{
int OptionSelected= 1;
int key;
bool stop = true;
do
{
system("cls");
gotoxy(5, 3 + OptionSelected); printf(">>");
gotoxy(15, 2); printf("%s", title1);
for (int i = 0; i < n_options1; i++)
{
gotoxy(10, 4 + i);
printf("%s ", options_menu1[i]);
}
do
{
key = _getch();
} while (key != KEY_UP && key != KEY_DOWN && key != KEY_ENTER );
switch (key)
{
case KEY_UP:
OptionSelected--;
if (OptionSelected < 1)
{
OptionSelected = n_options1;
}
break;
case KEY_DOWN:
OptionSelected--;
if (OptionSelected > n_options1)
{
OptionSelected = 1;
}
break;
case KEY_ENTER:
stop = false;
break;
}
} while (stop);
return OptionSelected;
}
The compiler reads your program top to bottom, so it sees:
option = Menu(title, options_menu, n_options);
On this line, you call a previously unknown function, Menu.
Because the function is unknown, the compiler assumes it will be int Menu(void). (takes no parameters, returns an int).
That assumption is obviously different from how Menu eventually gets declared.
To fix this, declare the function properly near the top of your file:
int Menu(const char *title1, const char *options_menu1[], int n_options1);
Then, when the compiler encounters your function-call, it will not assume a declaration, it will use the declaration you already provided (takes 3 parameters, and returns an int)

How to avoid multiple chain of if else

Hi I have a piece of code as below, I want to avoid multiple if else, is there a better approach for this:
if(strcmp(somename, "some") == 0)
{
fun();
}
else if(strcmp(somename,"some1") == 0)
{
fun();
}
else if(strcmp(somename,"some2") == 0)
{
fun();
}
else if(strcmp(somename,"some3") == 0)
{
fun();
}
You can use a pointer to pointer and a loop:
const char *ap[] = {"some", "some1", "some2", "some3", NULL};
const char **p = ap;
while (*p) {
if (strcmp(somename, *p) == 0) {
fun();
break;
}
p++;
}
Create a map (ordered or unordered) mapping values for somename to std::function instances to call.
You can try a simple approach using switch cases. For example, you can use it like
switch(somename) {
case "some1" :
fun1();
break;
case "some2" :
fun2();
break;
case "some3" :
fun3();
break;
default :
//some default case
}
also you can use str2int in c++11 in case switch does't work with strings well like
switch(str2int(somename)) {
case str2int("some1") :
fun1();
break;
case str2int("some2") :
fun2();
break;
case str2int("some3") :
fun3();
break;
default :
//some default case
}

Comments(/*...*/) longer than one line

I am supposed to count the /*...*/ comments in a file and I was wondering if this code is right or am I missing something out?
My Code
void commentsLongerThanOneLine(FILE* inputStream, FILE* outputStream) {
int count = 0, c, state = 1;
while ((c = fgetc(inputStream) != EOF)) {
switch (state) {
case 1: switch (c) {
case '/': state = 2; break;
}
break;
case 2: switch (c) {
case '/': state = 3; break;
case '*': state = 4; break;
default: state = 1;
}
break;
case 3: switch (c) {
case '\n': state = 1; break;
default: state = 4; count++;
}
break;
case 4:switch (c) {
case'*': if (c == '\n') count++; break;
default: state = 4; if (c == '\n') count++;
}
}
}
fprintf(outputStream, "Comments longer than one line: %d\n", count);
}

C SDL Keyboard Events SDL_KEYUP Triggering When Key Is Down

I am using SDL in C, and I'm trying to make a character move on the screen when a key is pressed, and stop when it is released, but it seems as if the KEYUP event is triggering when the key is still being held down. If I remove the KEYUP section in pressed(), the characters will slide across the screen, but obviously won't stop on their own. If I leave the KEYUP section in, I have to press the key repeatedly to move them across the screen.
Any idea what I'm doing wrong?
Here's what I have:
...
int done = 0;
while (done==0)
{
pressed();
if (kenter == 1)
{
state = 1;
subscreen();
}
if (kescape == 1)
{
done = 1;
}
if (kup == 1)
{
playery += -2;
}
if (kdown == 1)
{
playery += 2;
}
if (kright == 1)
{
playerx += 2;
}
if (kleft == 1)
{
playerx += - 2;
}
...
int pressed ()
{
SDL_Event keyevent;
while (SDL_PollEvent(&keyevent))
{
switch(keyevent.type)
{
case SDL_KEYDOWN:
switch(keyevent.key.keysym.sym)
{
case SDLK_RETURN:
{
kenter = 1;
break;
}
case SDLK_ESCAPE:
{
kescape = 1;
break;
}
case SDLK_a:
{
ka = 1;
break;
}
case SDLK_s:
{
ks = 1;
break;
}
case SDLK_UP:
{
kup = 1;
break;
}
case SDLK_DOWN:
{
kdown = 1;
break;
}
case SDLK_RIGHT:
{
kright = 1;
break;
}
case SDLK_LEFT:
{
kleft = 1;
break;
}
default:
break;
}
}
switch(keyevent.type)
{
case SDL_KEYUP:
switch(keyevent.key.keysym.sym)
{
case SDLK_RETURN:
{
kenter = 0;
break;
}
case SDLK_ESCAPE:
{
kescape = 0;
break;
}
case SDLK_a:
{
ka = 0;
break;
}
case SDLK_s:
{
ks = 0;
break;
}
case SDLK_UP:
{
kup = 0;
break;
}
case SDLK_DOWN:
{
kdown = 0;
break;
}
case SDLK_RIGHT:
{
kright = 0;
break;
}
case SDLK_LEFT:
{
kleft = 0;
break;
}
default:
break;
}
}
}
return 0;
}
I think your switch statements are broken.
Use this less confusing way
int pressed ()
{
SDL_Event event;
while(SDL_PollEvent(&event) )
{
if(event.type == SDLK_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_RETURN:
doStuff = 1
break;
default:
break;
}
}
if(event.type == SDLK_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_RETURN:
doStuff = 0;
break;
default:
break;
}
}
}
}
Also important:
SDL Tutorials: Practical Keyboard Input
Oh and avoid using global variables!
Your use of two switch statements is odd and confusing, you should probably fix that.
The issues you're seeing are likely due to keyboard repeat, see the SDL_EnableKeyRepeat() call for how to disable it.
don't use switch. I experienced same thing, but I resolved into using 'if' like this. Maybe switch has 'else if'.
if(event.type == SDL_KEYDOWN){
....
}
if(event.type == SDL_KEYUP){
....
}

Resources