Jumping from one case to the default case in switch statement - c

switch(ch){
case 'a':
//do something, condition does not match so go to default case
//don't break in here, and don't allow fall through to other cases.
case 'b':
//..
case 'c':
//..
case '_':
//...
default:
//
break;
}
In a switch statement like above one I enter case 'a', I break only if the condition inside it occurs, otherwise I want to jump to default case. Is there any other way of doing this rather than labels or gotos?

goto For The Win
switch (ch) {
case 'a':
if (1) goto LINE96532;
break;
case 'b':
if (1) goto LINE96532;
break;
LINE96532:
default:
//
break;
}

Just reorder the cases so that that case is the last:
switch(ch){
case 'b':
//..
case 'c':
//..
case '_':
//...
case 'a':
//do something, condition does not match so go to default case
if (condition)
break;
//don't break in here, and don't allow fall through to other cases.
default:
//
break;
}

If the condition doesn't depend on cases, why put it inside?
if (!condition){
// do default
}else{
switch(ch){
case 'a':
// do a
break;
...
}
}

Refactor your code:
int test_char(char ch)
{
switch(ch) {
case 'a': if (condition) return 0; break;
case 'b': // ...
default: return -1;
}
return 1;
}
...
// defaults processing switch
switch(test_char(ch)) {
case 0: break; // condition met
case 1: // default processing
default: // case not handled by test_char
}
This also adds the benefit of being flexible to test for multiple classes of default processing. Say you have a group of chars [c, d, e, f] which share some common logic. Simply return 2 from test_char() for these cases (possibly after some conditions has been tested), and add a case 2: handler to the default processing switch statement.

I'm not sure if thes is the best answer, but here it goes:
If you absolutely do not want to use labels, and you want to keep the cases in their current order, then you could continue after case 'a' and then check so see if(ch != 'a') at the beginning of each subsequent case, only executing the statement if the condition is true:
switch(ch){
case 'a':
// do something
case 'b':
if(ch != 'a') {
//do something
}
//repeat for each subsequent case
default:
//do something
break;
}
This is probably not the most efficient way to solve your problem, but it should accomplish what you want.

If you must have the switch statements first because the condition you're checking for depends on the case (or the case has to be evaluated first before you can check on the condition), simply set a flag inside your switch cases, and if that flag is set, then do a default operation. For instance:
int default_true = 0;
switch (case_value)
{
case 'a': /* if the condition is true, set the default_true flag */
case 'b': /* if the condition is true, set the default_true flag */
//...
default: default_flag = 1; // set the default_true flag to true
}
if (default_flag)
{
//place your "default" code here rather than inside the switch statement
//this prevents code reduplication
}

Here's what I did:
char ucResult = 1;
switch(ch){
case 'a':
if(ucResult){
// do something
if(error) ucResult = 0;
}
case 'b':
if(ucResult){
// do something
if(error) ucResult = 0;
}
case 'c':
if(ucResult){
// do something
if(error) ucResult = 0;
}
case '_':
if(ucResult){
// do something
if(error) ucResult = 0;
}
default:
//
break;
}
With this structure, you can switch to default case from any previous cases. Handy for breaking outer loops too.

I hope my solution answers your question. Simply let the cases follow through all the way (beginning with the matching case) but use a condition to disable subsequent cases from running.
typedef enum boolean
{
FALSE = 0, TRUE = 1
} bool;
void pstuff(char input)
{
bool _skip = FALSE;
switch(input)
{
case 'a':
printf("Case a.");
_skip = TRUE;
case 'b':
if(!_skip)
{
printf("Case b.");
_skip = TRUE;
}
case 'c':
if(!_skip)
{
printf("Case c.");
_skip = TRUE;
}
//...
default:
printf("Done!\n"); //Always gets printed.
}
}

Well, the post is really old but to answer everyone:
you can simple write 'goto default;' and you will directly jump to the default case without any problems.
Example:
switch (value)
{
case value1:
// do something;
break;
case value2:
// do something
break;
.
.
.
.
case value20:
// do something
**goto default;**
.
.
case valueN:
// do something
break;
default:
// do something
break;
}

Related

Are macros for large switch statements faster than functions with large switch statements?

So, for inline functions (1-2 statements) and small macros, it seems that there isn't too much of a performance difference between using a macro or an inline function.
However, given the function call overhead for a larger function, I am wondering for,
GCC 7.0
C language (not C++)
OSX (not sure if this would vary that much cross platform)
Would using large macros for a switch statement be faster than putting them in an equivalent function call? This is on my part assuming such large functions will not be inlined. Here is my example code.
#define LEX_CHAR(chPtr, tag) switch(*chPtr) { \
case 'a':\
case 'b':\
case 'c':\
case 'e':\
case '$': tag = Tag_A;\
break; \
case '0':\
case '1':\
case '2':\
case '3': tag = Tag_B;\
break;\
case 'r':\
if(chPtr[1] == 'd' || chPtr[1] == '#') tag = Tag_c;\
else tag = Tag_B;\
break;\
case '+':\
case '#':\
case '!':\
if(chPtr[1] == 'd') tag = Tag_C;\
case '-':\
case '^':\
tag = Tag_D;\
break;\
default:\
tag = Tag_B;\
}
enum Tag
{
Tag_A,
Tag_B,
Tag_C,
Tag_D
};
typedef enum Tag Tag;
void Lex_Char(char* chPtr, Tag* tag)
{
switch(*chPtr) {
case 'a':
case 'b':
case 'c':
case 'e':
case '$': *tag = Tag_A;
break;
case '0':
case '1':
case '2':
case '3': *tag = Tag_B;
break;
case 'r':
if(chPtr[1] == 'd' || chPtr[1] == '#') *tag = Tag_C;
else *tag = Tag_B;
break;
case '+':
case '#':
case '!':
if(chPtr[1] == 'd') *tag = Tag_C;
case '-':
case '^':
*tag = Tag_D;
break;
default:
*tag = Tag_B;
}
}
So between these two, the macro and the function, is there any optimization in using the macro over the function?
First, note that when you have code in a macro, the compiler must insert it inline in the calling code. When you make it a function, the compiler may insert it inline.
You should also understand what happens when you declare a function like:
void Lex_Char(char* chPtr, Tag* tag) { ... }
This tells the compiler that the function is accessible from other C files - the compiler has to make a full version of this function. Inlining the function would then mean making two copies of the code - one for the full function version, and one inlined at the call site. The compiler will be reluctant to do this unless your optimisation settings put a strong emphasis on size over speed.
If a function is only to be used within the current translation unit, you should mark it "static":
static void Lex_Char(char* chPtr, Tag* tag) { ... }
This tells the compiler that it is inaccessible from outside. If the function is only ever used once within the current module, then the compiler can happily inline it - doing so is "free".
You can also mark the function as "static inline", giving the compiler a hint that you are keen on it being inlined.
Of course, this all depends on having optimisation enabled for the compiler - if you don't enable optimisation, all your time testing is worthless.
An inlined static function is always a better choice than a macro (when you have the choice - macros can be more flexible than inline functions). The code is clearer to write, and you have better static warning and error checking. The resulting code (assuming optimisation) will be the same.
Your timing tests, incidentally, are pointless here - the compiler will see that the values involved don't change and will not run the function more than once, when it is inlined and optimisation is enabled. It might not run it at all, but pre-calculate the result at compile time.
Oh, and you've forgotten a "break" in the case '!'.
So it turns out after a timed test, and repeated under an identical for loop, the macro version is about twice as fast as the regular function.
Here's is my complete timer and full file compiled to produce the result
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#define LEX_CHAR(chPtr, tag) switch(*chPtr) { \
case 'a':\
case 'b':\
case 'c':\
case 'e':\
case '$': tag = Tag_A;\
break; \
case '0':\
case '1':\
case '2':\
case '3': tag = Tag_B;\
break;\
case 'r':\
if(chPtr[1] == 'd' || chPtr[1] == '#') tag = Tag_C;\
else tag = Tag_B;\
break;\
case '+':\
case '#':\
case '!':\
if(chPtr[1] == 'd') tag = Tag_C;\
case '-':\
case '^':\
tag = Tag_D;\
break;\
default:\
tag = Tag_B;\
}
enum Tag
{
Tag_A,
Tag_B,
Tag_C,
Tag_D
};
typedef enum Tag Tag;
void Lex_Char(char* chPtr, Tag* tag)
{
switch(*chPtr) {
case 'a':
case 'b':
case 'c':
case 'e':
case '$': *tag = Tag_A;
break;
case '0':
case '1':
case '2':
case '3': *tag = Tag_B;
break;
case 'r':
if(chPtr[1] == 'd' || chPtr[1] == '#') *tag = Tag_C;
else *tag = Tag_B;
break;
case '+':
case '#':
case '!':
if(chPtr[1] == 'd') *tag = Tag_C;
case '-':
case '^':
*tag = Tag_D;
break;
default:
*tag = Tag_B;
}
}
int main(){
Tag tagPnt = Tag_D;
char* code = "#he";
clock_t start, end;
start = clock();
//for(size_t i = 0; i<10000;i++) Lex_Char(code, &tagPnt); Number of seconds: 0.000067
for(size_t i = 0; i<10000;i++) LEX_CHAR(code, tagPnt); // Number of seconds: 0.000032
end = clock();
printf( "Number of seconds: %f\n", (end-start)/(double)CLOCKS_PER_SEC );
printf("%d is tag\n", tagPnt);
return 0;
}
Result:
Function: 0.000067
Macro: 0.000032

C - Case statement failing to compare variable

I'm a little confused with the case statement in the PrintGenre function; it passes the value correctly, but defaults to Undefined.
Little bit of background; this is ultimately becoming a (very simple) text music player, and I think I've found an easier way to do this, but just for my overall understanding I wanted to figure out why this case statement isn't functioning the way I wanted it to.
If I remove the default option, it goes to the last case option in the list.
I'm fairly new to the C language, so if there's anything I'm misunderstanding please let me know.
#include "terminal_user_input.h"
#include <stdio.h>
#include <string.h>
enum musicGenre {Pop, Alternative_Rock, Electronic, Undefined};
struct Album
{
my_string Title;
my_string Artist;
int Year;
enum musicGenre Genre;
};
my_string PrintGenre(int Genre)
{
//Variables
my_string result;
printf("%d", Genre); //outputs correctly
switch (Genre)
{
case 0:
strcpy(result.str, "Pop");
case 1:
strcpy(result.str, "Alternative Rock");
case 2:
strcpy(result.str, "Electronic");
default:
strcpy(result.str, "Undefined");
}
return result;
}
int main()
{
// Variables
struct Album Album1;
int choice;
printf("1. Pop\n");
printf("2. Alternative Rock\n");
printf("3. Electronic\n");
choice = read_integer("Please select a genre: ");
switch (choice)
{
case 1:
Album1.Genre = 0;
break;
case 2:
Album1.Genre = 1;
break;
case 3:
Album1.Genre = 2;
break;
default:
Album1.Genre = 3;
break;
}
printf("%d", Album1.Genre);
printf("The genre of Album 1 is %s", PrintGenre(Album1.Genre).str);
return 0;
}
In your code,
switch (Genre)
{
case 0:
strcpy(result.str, "Pop");
case 1:
strcpy(result.str, "Alternative Rock");
case 2:
strcpy(result.str, "Electronic");
default:
strcpy(result.str, "Undefined");
}
all the case statements bodies are missing a break; statement, which makes it a fall-through switch.
To avoid this "undesired" behaviour, you need to add a break; statement every time you want to limit the flow of program to a certain part of the body.
Quoting the example from the C11 standard, chapter ยง6.8.4.2/P7
EXAMPLE In the artificial program fragment
switch (expr)
{
int i = 4;
f(i);
case 0:
i = 17;
/* falls through into default code */ << --- NOTE HERE
default:
printf("%d\n", i);
}
add break;
switch (Genre)
{
case 0:
strcpy(result.str, "Pop"); break;
case 1:
strcpy(result.str, "Alternative Rock"); break;
case 2:
strcpy(result.str, "Electronic"); break;
default:
strcpy(result.str, "Undefined");
}

C programming - enum switch case with TCHAR

I am doing a win32 program with C and I do not know how to do a enum and switch case with UNICODE.
I receive from the client a named pipe with this structure
typedef struct {
TCHAR UtilOrigem[10];
TCHAR Comando[3]; // Comando
TCHAR Argumento1[10];
}cmd;
cmd.comando have values "00", "01", "02" .....
And I want to do a switch case with cmd.comando.
Please help me.
Thanks
Carlos
Try this:
int val = _ttoi(cmd.comando);
switch (val)
{
case 0:
...
break;
case 1:
...
break;
case 2:
...
break;
...
}
Or even simpler:
int val = 10*(cmd.comando[0]-L'0')+(cmd.comando[1]-L'0');
switch (val)
{
case 0:
...
break;
case 1:
...
break;
case 2:
...
break;
...
}

nested switch case not working [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am trying to execute some commands using USART communication and reading some values using ATmega32-A. have a look at my code . My problem is i am trying to add some cases (nested switch case) but i am not getting what i want. I hope i am giving all most all information required to solve my problem.
void uniCom(void) {
switch (Command) {
/* ... */
case (muxsel):
printf(muxselection);
switch (c) {
case 1:
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
Command = 0;
break;
case 2:
/*-------------------*/
break;
}
Command = 0;
break;
/* ... */
default:
Command = 0;
break;
}
}
The problem is undefined c. And I don't see any declaration of muxselection, maybe missing "" ? Now the second approach.
void selcase(void) {
unsigned char c;
printf("muxselection");
while (rx_counter0) {
c = getchar();
switch (c) {
case 1:
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
Command = 0;
break;
case 2:
/*-------------------*/
break;
}
}
}
void uniCom(void) {
switch (Command) {
/* ... */
case (muxsel):
printf(muxselection);
selcase();
Command = 0;
break;
/* ... */
default:
Command = 0;
break;
}
}
My problem is i am executing all the commands as i declared but i want to select some more cases in one of the main switch case command "muxsel". for that i wrote nested switch case. if i select "muxsel" command on hyperteminal then it is printing like "muxselection" then if i enter 1 to select "case '1'"in second switch, nothing is printing. it is printing "command not found". what is the problem. I want execute nested switch but i am not able to do that using above code I have tried like this also.
void selcase(void) {
unsigned char c;
printf("muxselection");
while (rx_counter0) {
c = getchar();
switch (c) {
case '1':
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
c= 0;
break;
case '2':
/*-------------------*/
break;
default;
break;
}
}
}
creating one function for nested switch case and calling in main switch case as shown below.
void uniCom(void) {
switch (Command) {
/* ... */
case (muxsel):
printf(muxselection);
selcase();
Command = 0;
break;
/* ... */
default:
Command = 0;
break;
}
}
this way also not working please suggest me how to overcome this problem. i want to select one of the command in main switch case such as "muxsel" after that i have select mux channels using case statement. any help appreciated.
Thanks in advance.
I have solved this problem.
OK... the code isn't terribly clear, but I think I see your problem.
You tried to modify the code like this:
case (muxsel):
printf(muxselection);
switch (c) {
case 1:
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
Command = 0;
break;
case 2:
First, you don't have c declared in the scope of the uniCom() function. So that would not compile. Because you didn't give full code I assume you know that and probably really did something like this:
void uniCom(void) {
unsigned char c;
c = getchar();
switch (Command) {
case (no_com):
Command = 0;
....
case (muxsel):
printf("muxselection\n"); //Need quotes here and maybe a \n?
switch (c) {
case 1:
...
Which leads to the next problem. You're asking for a char c but your cases are built on an int. For example, if the user enters 3, what you're getting is the character '3' or the int 51. Check the ASCII Table
So your cases are for start of header (SOH), start of text (STX), etc right now... that's not going to work the way you wanted it to. You need to either do this:
switch (c) {
case 51: // This is ASCII '1'
...
break;
case 52: // This is ASCII '2'
Or do this:
switch (c) {
case '1':
...
break;
case '2':
Since you didn't give your input, or how c was defined, I could be wrong... but I'm going to wager that's your problem. By the way, make sure you have a default case at the end with a message like "bad input", it makes this type of thing easier to catch.
EDIT:
Modify the code as follows and share the result:
void runCom(void){
unsigned char c;
c = getchar();
printf("%c %d\n", c, c); //<-- add this line here
switch(Command){
and
void selcase(void) {
unsigned char c;
printf("muxselection");
while (rx_counter0) {
c = getchar();
printf("%c %d\n", c, c); //<-- and this line here
switch (c) {
I wrote it as an answer 'cause there is no place for it in comments. Although it's definitely not a final satisfactory once, it might help you get there.
For now I see two problems. You say you tried altering case(muxsel). Your code cannot even compile in my opinion. The code for the function should look similar to this:
void uniCom(void) {
switch (Command) {
/* ... */
case (muxsel):
printf(muxselection);
switch (c) {
case 1:
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
Command = 0;
break;
case 2:
/*-------------------*/
break;
}
Command = 0;
break;
/* ... */
default:
Command = 0;
break;
}
}
The problem is undefined c. And I don't see any declaration of muxselection, maybe missing "" ?
Now the second approach.
void selcase(void) {
unsigned char c;
printf("muxselection");
while (rx_counter0) {
c = getchar();
switch (c) {
case 1:
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
Command = 0;
break;
case 2:
/*-------------------*/
break;
}
}
}
void uniCom(void) {
switch (Command) {
/* ... */
case (muxsel):
printf(muxselection);
selcase();
Command = 0;
break;
/* ... */
default:
Command = 0;
break;
}
}
The second case could compile probably. The thing I do not understand is, why in the 2nd case you do manually read c. While in the former you do not ? Should it be loaded within uniCom routine or not ? It sure is in getCom(). Maybe you should not mess with buffers from the level of uniCom or below. Also are you sure that while(rxcounter0) will ever stop ? And if getchar() means to read a character from standard input from a human user typing on a keyboard it might be hard to read 1 or 2 from him as these are pretty low ASCII codes not present there.

GNU compiler KEY_F not detecting function keys

Basically, I have key detection for my console application, for some reason it's not detecting function keys.
Here is my code, I'm using GNU compiler on linux. Any help or ideas would be greatly appreciated.
refresh();
key = getch();
switch(key) {
case KEY_HOME: key = HOME; break;
case KEY_END: key = END; break;
case KEY_UP: key = UP; break;
case KEY_DOWN: key = DOWN; break;
case KEY_LEFT: key = LEFT; break;
case KEY_RIGHT: key = RIGHT; break;
case KEY_NPAGE: key = PGDN; break;
case KEY_PPAGE: key = PGUP; break;
case KEY_DC: key = DEL; break;
case KEY_IC: key = INSERT; break;
case KEY_F(1): key = F(1); break;
case KEY_F(2): key = F(2); break;
case KEY_F(3): key = F(3); break;
case KEY_F(4): key = F(4); break;
case KEY_F(5): key = F(5); break;
case KEY_F(6): key = F(6); break;
case KEY_F(7): key = F(7); break;
case KEY_F(8): key = F(8); break;
case KEY_F(9): key = F(9); break;
case KEY_F(10): key = F(10); break;
case KEY_F(11): key = F(11); break;
case KEY_F(12): key = F(12); break;
case KEY_ENTER: key = ENTER; break;
case KEY_BACKSPACE: key = BACKSPACE; break;
default:
//key = F(2); //For any function keypress, it jumps to default
if (NON_ASCII(key) != 0)
key = UNKNOWN;
}
I'm not a curses expert, but a bit of reading man pages netted me this program:
#include <curses.h>
int main()
{
int key;
initscr(); cbreak(); noecho();
while (1)
{
key = getch();
printw ("%u\n", key);
}
return 0;
}
When I press an F key, I get a 3-character sequence: 27, 79, (80 + N-1) where N is the number of the F key. I think your switch will have to recognize that the key is an escape sequence and handle it specially.
Edit: That pattern holds only for F1-F4. F5 changes it up. You'll probably want to incorporate the F(n) macros from curses.
Having the same issue, personally.
Casting the F(n) macro to a char type magically cleared the issue for me;
cmd = getch();
switch(cmd){
case 'r':
addch('r');
break;
case 'w':
addch('x');
break;
default:
if(cmd == (char)KEY_F(2)){ endwin(); exit(0); }
}
and the like. Worked for F2 through F10 plus F12. F's 1, 10 and 11 are "occupied" for lack of a better word on my xterm. (F1 opens the help window, F11 toggles fullscreen mode, etc.) Again, I can't emphasize enough that I couldn't begin to guess why that works.
You may need to enable the "keypad" functionality of the terminal using the keypad function. From the keypad(3x) manual page:
int keypad(WINDOW *win, bool bf);
The keypad option enables the keypad of the user's terminal. If enabled
(bf is TRUE), the user can press a function key (such as an arrow key) and
wgetch returns a single value representing the function key, as in
KEY_LEFT. If disabled (bf is FALSE), curses does not treat function
keys specially and the program has to interpret the escape sequences itself.
If the keypad in the terminal can be turned on (made to transmit) and off
(made to work locally), turning on this option causes the terminal keypad to be
turned on when wgetch is called. The default value for keypad is false.

Resources