Switch statement doesn't work with enum (C++) - c++

enum Maximum_Value{
MAXIMUM_VALUE_1 = 0,
MAXIMUM_VALUE_7 = 1,
MAXIMUM_VALUE_15 = 2,
MAXIMUM_VALUE_26 = 3,
MAXIMUM_VALUE_34 = 4
};
int value_from_function = functionetc();
switch(value_from_function){
MAXIMUM_VALUE_1: printf("MAXIMUM_VALUE_1 :%x\n",value_from_function); break;
MAXIMUM_VALUE_7: printf("MAXIMUM_VALUE_7 :%x\n",value_from_function); break;
MAXIMUM_VALUE_15: printf("MAXIMUM_VALUE_15 %x\n",value_from_function); break;
MAXIMUM_VALUE_26: printf("MAXIMUM_VALUE_26 %x\n",value_from_function); break;
MAXIMUM_VALUE_34: printf("MAXIMUM_VALUE_34 %x\n",value_from_function); break;
default: printf("default :%x\n",value_from_function);
}
The code above always seems to hit the default statement, printing "default :0" even though that should hit MAXIMUM_VALUE_1.
I've tried casting the variable in switch to no effect
I guess I should save the return value into a variable of type "Maximum_Value", but why doesn't the code work anyway?
Edit: Thanks for pointing out the awfully stupid mistake everyone :P. The root of the problem was copying coding from systemverilog, which uses 'case' as a keyword instead of 'switch', and doesn't require 'case' at the start of each case

Enumerators aren't labels but switch statements jump to labels. You use case to create a label switch statements can jump to:
case MAXIMUM_VALUE_1: ...; break;

Add case keyword then it will work.
case MAXIMUM_VALUE_1: printf("MAXIMUM_VALUE_1 :%x\n",value_from_function); break;
case MAXIMUM_VALUE_7: printf("MAXIMUM_VALUE_7 :%x\n",value_from_function); break;
case MAXIMUM_VALUE_15: printf("MAXIMUM_VALUE_15 %x\n",value_from_function); break;
case MAXIMUM_VALUE_26: printf("MAXIMUM_VALUE_26 %x\n",value_from_function); break;
case MAXIMUM_VALUE_34: printf("MAXIMUM_VALUE_34 %x\n",value_from_function); break;
default: printf("default :%x\n",value_from_function);

you are missing the case keyword before every label!
syntax of switch case is-
switch(type){
case type1: ....; break;
case type2: ....; break;
......
default: .....;
}

Related

how to only indent brackets after case labels using clang-format

I wanna a style that only indent brackets after case labels, while keeping case label not indented.
this is what I want:
switch(a)
{
case 1:
{
do_some_thing();
}
break;
}
I find an option IndentCaseLabels, but it will the whole things include the case label, neither true or false isn't what I want
true:
switch(a)
{
case 1:
{
do_some_thing();
}
break;
}
false:
switch(a)
{
case 1:
{
do_some_thing();
}
break;
}
Is this style possible in clang-format? If is, how could I Configure it?
It's just immediate above one you found in the manual.
IndentCaseBlocks: true
Indent case label blocks one level from the case label.
false: true:
switch (fool) { vs. switch (fool) {
case 1: { case 1:
bar(); {
} break; bar();
default: { }
plop(); break;
} default:
} {
plop();
}

Defining variables esp32

i am trying to figure out a way in esp32 to have (a list) for lack of better terms, that i could call upon as a variable input. I have a void playwav(); function. I want to use a global variable to define the file that should be played. ie playwav('alarm'). I had a case switch setup but was using the a b c method. As my code is growing (next step is going to add 71 new wav files), i am quickly realizing that method will no longer work. I have been told to do an array but for the life of me no matter what ive read i just cant grasp how to do it nor call upon the files by name. Does anyone have advice on what i should do? Any help is much appreciated.
This is what i currently have.
void playWAV (char effect, int bg1248_general_volume)
{
Serial.println("Entered playWAV");
switch (effect)
{
case 'a':
file = new AudioFileSourceSD("/wav/alarm.wav");
break;
case 'b':
file = new AudioFileSourceSD("/wav/alarmhigh.wav");
break;
case 'c':
file = new AudioFileSourceSD("/wav/alarmlow.wav");
break;
case 'd':
file = new AudioFileSourceSD("/wav/error.wav");
break;
case 'e':
file = new AudioFileSourceSD("/wav/error1.wav");
break;
case 'f':
file = new AudioFileSourceSD("/wav/noread.wav");
break;
case 'g':
file = new AudioFileSourceSD("/wav/noreadings.wav");
break;
case 'h':
file = new AudioFileSourceSD("/wav/normalrange.wav");
break;
case 'i':
file = new AudioFileSourceSD("/wav/warning.wav");
break;
case 'j':
file = new AudioFileSourceSD("/wav/warninghigh.wav");
break;
case 'k':
file = new AudioFileSourceSD("/wav/warninglow.wav");
break;
case 'l':
file = new AudioFileSourceSD("/wav/startup.wav");
break;
case 'm':
file = new AudioFileSourceSD("/wav/startup.wav");
break;
case 'n':
file = new AudioFileSourceSD("/wav/update.wav");
break;
case 'o':
file = new AudioFileSourceSD("/wav/startup_dev.wav");
}
float volumeGain = ((float)bg1248_general_volume / 100.0) * 39.0;
Serial.print("volumeGain:");
Serial.println(volumeGain);
id3 = new AudioFileSourceID3(file);
out = new AudioOutputI2S(0, 0); // Output to builtInDAC
out->SetPinout(12, 0, 2);
out->SetOutputModeMono(true);
out->SetGain(volumeGain);
wav = new AudioGeneratorWAV();
wav->begin(id3, out);
However because I used the alphabet im going to run out of cases very very soon. I want to be able to call for a specific wav file anywhere in the project preferably like playWAV(filename) or something similar.
I call the function(file) like this (example condition)
if((ns->sensSgv<=cfg.snd_alarm) && (ns->sensSgv>=0.1)) {
// red alarm state
// M5.Lcd.fillRect(110, 220, 100, 20, TFT_RED);
Serial.println("ALARM LOW");
M5.Lcd.fillRect(0, 220, 320, 20, TFT_RED);
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
int stw=M5.Lcd.textWidth(tmpStr);
M5.Lcd.drawString(tmpStr, 159-stw/2, 220, GFXFF);
if( (alarmDifSec>cfg.alarm_repeat*60) && (snoozeRemaining<=0) ) {
playWAV('a', 100);
'a'=case 100 = volume.
Alan, this is what I currently had in my enum, i was following a tutorial but doubt i did it right. even if i did i was getting errors saying i had duplicate cases when i don't.
EDIT:
The condition is set using this:
if((ns->sensSgv<=cfg.snd_alarm) && (ns->sensSgv>=0.1))
and if you notice at the bottom there is:
if( (alarmDifSec>cfg.alarm_repeat*60) && (snoozeRemaining<=0) ) {
playWAV('a', 100);
The a corelates to the case A in the switch case. shown above. currently all the places that use the playWAV function are manually specified.
My understanding was using the alphabets in switch case will ran out soon because of large no. of files (>26). So, I implemented the logic using enum first and below is the complete code.
#include<stdio.h>
enum soundEffects {
alarm,
alarm_high,
alarm_low,
Dev_startup,
error,
error1,
noread,
noreadings,
normalrange,
startup,
startup_dev,
update,
warning,
warning_high,
warning_low,
};
void playWav (enum soundEffects effect, int paci_volume)
{
//Serial.println("Entered paciplay_day");
//printf("Entered paciplay_day\n");
switch (effect)
{
case alarm:
//file = new AudioFileSourceSD("/wav/alarm.wav");
printf("/wav/alarm.wav\n");
break;
case alarm_high:
//file = new AudioFileSourceSD("/wav/alarmhigh.wav");
printf("/wav/alarmhigh.wav\n");
break;
case alarm_low:
//file = new AudioFileSourceSD("/wav/alarmlow.wav");
printf("/wav/alarmlow.wav\n");
break;
case error:
//file = new AudioFileSourceSD("/wav/error.wav");
printf("/wav/error.wav\n");
break;
case error1:
//file = new AudioFileSourceSD("/wav/error1.wav");
printf("/wav/error1.wav\n");
break;
case noread:
//file = new AudioFileSourceSD("/wav/noread.wav");
printf("/wav/noread.wav\n");
break;
case noreadings:
//file = new AudioFileSourceSD("/wav/noreadings.wav");
printf("/wav/noreadings.wav\n");
break;
case normalrange:
//file = new AudioFileSourceSD("/wav/normalrange.wav");
printf("/wav/normalrange.wav\n");
break;
case warning:
//file = new AudioFileSourceSD("/wav/warning.wav");
printf("/wav/warning.wav\n");
break;
case warning_high:
//file = new AudioFileSourceSD("/wav/warninghigh.wav");
printf("/wav/warninghigh.wav\n");
break;
case warning_low:
//file = new AudioFileSourceSD("/wav/warninglow.wav");
printf("/wav/warninglow.wav\n");
break;
case startup:
//file = new AudioFileSourceSD("/wav/startup.wav");
printf("/wav/startup.wav\n");
break;
case update:
//file = new AudioFileSourceSD("/wav/update.wav");
printf("/wav/update.wav\n");
break;
}
}
int main()
{
//below are the 3 ways of calling your playWav() function
//1 - using direct numbers
//this will throw compilation error when compiled using cpp compilers
for (int i = 0; i<14; i++)
{
printf("enum value: %d\n", i);
playWav(i, 50);
}
//2 - directly calling using the enum
playWav(startup, 100);
//3 - Just another way of calling
enum soundEffects sound;
sound = error;
playWav(sound, 100);
return 0;
}
Also, I implemented this same logic using double array's. Please do find it below. This uses the name of the file as a parameter so altogether we can eliminate the use of switch statement.
#include<stdio.h>
void playWav (const char *filename, int paci_volume)
{
//Serial.println("Entered paciplay_day");
printf("Entered paciplay_day\n");
//file = new AudioFileSourceSD("/wav/update.wav");
printf("/wav/%s\n", filename);
}
int main()
{
const char list_of_files[][25] = { "startup.wav", "update.wav", "warning.wav", "alarm.wav" };
for (int i = 0; i<4; i++)
{
printf("name: %s\n", list_of_files[i]);
playWav(list_of_files[i], 50);
}
return 0;
}
Please omit my printf statements which I used for debugging. I hope this is useful.

C++ #defining enum states

I am wondering if I made a good decision when I defined all states of my enum to their shorter counterparts: just to tidy up the code.Code:Enum:
enum class ESelectedCharacterState : uint8
{
SS_WantsWalk,
SS_WantsJog,
SS_WantsCrouch,
SS_WantsProne,
SS_WantsJump
};
Defining:
#define WantsWalk ESelectedCharacterState::SS_WantsWalk
#define WantsJog ESelectedCharacterState::SS_WantsJog
#define WantsCrouch ESelectedCharacterState::SS_WantsCrouch
#define WantsProne ESelectedCharacterState::SS_WantsProne
#define WantsJump ESelectedCharacterState::SS_WantsJump
Case with no #defined enum states:
switch (StateSelected)
{
case ESelectedCharacterState::SS_WantsWalk:
break;
case ESelectedCharacterState::SS_WantsJog:
break;
case ESelectedCharacterState::SS_WantsCrouch:
break;
case ESelectedCharacterState::SS_WantsProne:
break;
case ESelectedCharacterState::SS_WantsJump:
break;
default:
break;
}
Case with #defined enum states:
switch (StateSelected)
{
case WantsWalk:
break;
case WantsJog:
break;
case WantsCrouch:
break;
case WantsProne:
break;
case WantsJump:
break;
default:
break;
}
This is actually a small bit of code but I use this enum very frequently in my project.
Using a typedef would be a cleaner way to achieve this, by making your enum's type shorter.
typedef ESelectedCharacterState ESCS;

C++ Forced to do a weird cast to get rid of "expression should be a modifiable lvalue" [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I just faced a strange enum assignation problem and I thought you could have helped me out. I have an enum like this:
enum LIB_EDXENGINE CameraFeatureDataType
{
CFDT_ENUMERATION,
CFDT_64BITS_UINT,
CFDT_64BITS_INT,
CFDT_64BITS_FLOAT,
CFDT_BOOLEAN,
CFDT_32BITS_UINT,
CFDT_32BITS_INT,
CFDT_32BITS_FLOAT,
};
And I have a class with an instance of this enum.
EDITED:
const CameraFeatureDataType & LibEDX::CVBGenicamFeature2::GetFeatureType() const
{
switch (m_eNodeType)
{
case NT_Boolean:
m_eCameraFeatureDataType = CFDT_BOOLEAN;
break;
case NT_Integer:
m_eCameraFeatureDataType = CFDT_64BITS_INT;
break;
case NT_Float:
m_eCameraFeatureDataType = CFDT_64BITS_FLOAT;
break;
case NT_Enumeration:
m_eCameraFeatureDataType = CFDT_ENUMERATION;
break;
}
return m_eCameraFeatureDataType;
}
The only solution that I found to get rid of the error is to cast the member variable to its own type, which is weird I think.
EDITED TOO:
const CameraFeatureDataType & LibEDX::CVBGenicamFeature2::GetFeatureType() const
{
switch (m_eNodeType)
{
case NT_Boolean:
(CameraFeatureDataType)m_eCameraFeatureDataType = CFDT_BOOLEAN;
break;
case NT_Integer:
(CameraFeatureDataType)m_eCameraFeatureDataType = CFDT_64BITS_INT;
break;
case NT_Float:
(CameraFeatureDataType)m_eCameraFeatureDataType = CFDT_64BITS_FLOAT;
break;
case NT_Enumeration:
(CameraFeatureDataType)m_eCameraFeatureDataType = CFDT_ENUMERATION;
break;
}
return m_eCameraFeatureDataType;
}
You declared method as const and then you do member attribute modification:
const CameraFeatureDataType & LibEDX::CVBGenicamFeature2::GetFeatureType() const
{
switch (m_eNodeType)
{
case NT_Boolean:
this->m_eCameraFeatureDataType = CFDT_BOOLEAN;
break;
case NT_Integer:
this->m_eCameraFeatureDataType = CFDT_64BITS_INT;
break;
case NT_Float:
this->m_eCameraFeatureDataType = CFDT_64BITS_FLOAT;
break;
case NT_Enumeration:
this->m_eCameraFeatureDataType = CFDT_ENUMERATION;
break;
}
return this->m_eCameraFeatureDataType;
}
You propably should write:
const CameraFeatureDataType & LibEDX::CVBGenicamFeature2::GetFeatureType() const
{
switch (m_eNodeType)
{
case NT_Boolean:
return CFDT_BOOLEAN;
case NT_Integer:
return CFDT_64BITS_INT;
case NT_Float:
return CFDT_64BITS_FLOAT;
case NT_Enumeration:
return CFDT_ENUMERATION;
}
return CFDT_UNKNOWN;//change to default value
}
Your problem is that you are trying to modify a member variable in a const method.
This is what your method would look like normally:
CameraFeatureDataType LibEDX::CVBGenicamFeature2::GetFeatureType() const
{
switch (m_eNodeType)
{
case NT_Boolean:
return CFDT_BOOLEAN;
case NT_Integer:
return CFDT_64BITS_INT;
case NT_Float:
return CFDT_64BITS_FLOAT;
case NT_Enumeration:
return CFDT_ENUMERATION;
default:
// don't know either, you decide...
}
}
I have no idea why you even have a member variable, or why you would return an enum value as a const reference. If you need one of those, you should think hard about why you need them. The keyword for changing a member variable in a constmethod is mutable.

calculation of month as per Julian Calendar

I'm a beginner in QT C++, and I'm trying to print Julian day on a label_j with respect the value mentioned in array list. I'm unable to do that. Please could you see and correct it. Thanks a lot in advance.
Current month is been fetch from the UTC,
if month equal jan then print 0,
month equal then print 31,
month equal March then print 59 and so on until it reach December.
void MainWindow::getJulianDay()
{
int month_arr[]={0,31,59,90,120,151,181,212,243,273,304,334};
QString January, February, March, April, May, June, July, August, September, October, November, December;
QDateTime local(QDateTime::currentDateTimeUtc());
QDateTime UTC(local.toUTC());
QString month=UTC.toString("MMMM");
switch (month)
{
case January:
month=month_arr[0];
break;
case February:
month=month_arr[1];
break;
case March:
month=month_arr[2];
break;
case April:
month=month_arr[3];
break;
case May:
month=month_arr[4];
break;
case June:
month=month_arr[5];
break;
case July:
month=month_arr[6];
break;
case August:
month=month_arr[7];
break;
case September:
month=month_arr[8];
break;
case October:
month=month_arr[9];
break;
case November:
month=month_arr[10];
break;
case December:
month=month_arr[11];
break;
default: month=invalid;
break;
ui->label_j->setText(month);
}
I see two main mistakes :
First of all, your case statement conditions are empty. You should do :
switch(variable) {
case condition1:
...
break;
case condition2:
...
break;
...
default:
...
break;
}
So, your code becomes :
switch (month);
{
case 1:
month="January";
answer=month_arr[0];
break;
case 2:
month="February";
answer=month_arr[1];
break;
...
default:
month="invalid";
break;
}
The second main problem is that ui->label_j->setText(answer); should be out of the switch loop. As it is currently, this statement will never be executed.
Edit : As noticed by m7913d, you have a lot of type errors. Review the type of your variables !