C programming - enum switch case with TCHAR - c

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;
...
}

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");
}

Trying to access string in struct causes segmentation fault

It's my first time posting a question here and i'll try to be as precise as I can.So i have this project and when i try to access a string in a struct it gives me a segmentation fault.
struct InfoSession {
TabNodePtr FirstTab;
TabNodePtr LastTab;
TabNodePtr CurrTab;
TabNodePtr AuxTab;
char* OpeningAddress;};
this is the struct included in the Session.c file where i have all the functions that i want to call in my main.
void SessionNewOpeningAddress(char * OpeningAddress,InfoSessionPtr Session){
scanf("%s",&OpeningAddress);
strcpy(Session->OpeningAddress,OpeningAddress);}
this is one of the functions that cause a segmentation fault(after testing i realised that each function that calls Session->OpeningAddresscause a segmentation fault.)This is my main.c where my main is included.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Session.h"
int main(int argc, char *argv[]) {
InfoSessionPtr MySession=NULL;
int option;
char OpeningAddress;
do{
printf("\n\n1. Create Session.\n\
2. Create new tab.\n\
3. Go to next tab.\n\
4. Go to previous tab.\n\
5. Move tab left.\n\
6. Move tab right.\n\
7. Set new opening address.\n\
8. Show the default opening address.\n\
9. Go to next site.\n\
10.Go to previous site.\n\
11.Show the current address.\n\
12.Close the current tab.\n\
13.Close session.\n\
14.Open a new address.\n\
Dwste thn epilogh sas(1-14, 0 gia eksodo):");
scanf("%d",&option);
switch(option)
{case 1:
SessionNew(&OpeningAddress);
MySession =&SessionNew;
printf("The Session has been created!");
break;
case 2:
SessionNewTab(MySession);
break;
case 3:
SessionTabNext(MySession);
break;
case 4:
SessionTabPrev(MySession);
break;
case 5:
SessionTabMoveLeft(MySession);
break;
case 6:
SessionTabMoveRight(MySession);
break;
case 7:
printf("Dwste nea dieuthinsi gia default\n");
SessionNewOpeningAddress(&OpeningAddress,MySession);
break;
case 8:
SessionShowOpeningAddress(MySession);
break;
case 9:
SessionSiteNext(MySession);
break;
case 10:
SessionSitePrev(MySession);
break;
case 11:
SessionAddressShow(MySession);
break;
case 12:
SessionTabClose(MySession);
break;
case 13:
SessionClose(MySession);
break;
case 14:
SessionNewAddress(&OpeningAddress,MySession);
break;
}
}while(option);
return 0;}
I've searched all over the internet but i still cant understand where the problem is.Anyone that can help me please reply as fast as you can.
Oh and the SessionNew function is here(everything works fine in this function):
InfoSessionPtr SessionNew(char * OpeningAddress){
TabNodePtr Tab;
InfoSessionPtr IS;
SiteNodePtr Site;
IS=malloc(sizeof(struct InfoSession));
Tab=malloc(sizeof(struct TabNode));
Site=malloc(sizeof(struct SiteNode));
IS->OpeningAddress=malloc(strlen(OpeningAddress)+1);
Site->Address=malloc(strlen(OpeningAddress)+1);
IS->AuxTab = NULL;
IS->CurrTab = Tab;
IS->FirstTab = Tab;
IS->LastTab = Tab;
Tab->NextTab = Tab;
Tab->PrevTab = Tab;
Site->UpTab = Tab;
Tab->CurrSite = Site;
Tab->FirstSite = Site;
OpeningAddress = "google";
strcpy(IS->OpeningAddress,OpeningAddress);
strcpy(Site->Address,IS->OpeningAddress);}
Consider this. I moved the statement OpeningAddress = "google"; before the malloc and changed it to strcpy. As I did nt have the session.h file and the other functions, i removed those references.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct InfoSession {
char* OpeningAddress;};
typedef struct InfoSession *InfoSessionPtr;
void SessionNewOpeningAddress(char * OpeningAddress,InfoSessionPtr Session){
scanf("%39s",OpeningAddress);
strcpy(Session->OpeningAddress,OpeningAddress);}
InfoSessionPtr SessionNew(char * OpeningAddress){
InfoSessionPtr IS;
IS=malloc(sizeof(struct InfoSession));
strcpy ( OpeningAddress, "google");
IS->OpeningAddress=malloc(strlen(OpeningAddress)+1);
strcpy(IS->OpeningAddress,OpeningAddress);
return IS;}
int main(int argc, char *argv[]) {
InfoSessionPtr MySession=NULL;
int option;
char OpeningAddress[40] = "g";
do{
printf("\n\n1. Create Session.\n\
2. Create new tab.\n\
3. Go to next tab.\n\
4. Go to previous tab.\n\
5. Move tab left.\n\
6. Move tab right.\n\
7. Set new opening address.\n\
8. Show the default opening address.\n\
9. Go to next site.\n\
10.Go to previous site.\n\
11.Show the current address.\n\
12.Close the current tab.\n\
13.Close session.\n\
14.Open a new address.\n\
Dwste thn epilogh sas(1-14, 0 gia eksodo):");
scanf("%d",&option);
switch(option)
{case 1:
MySession = SessionNew(OpeningAddress);
printf("The Session has been created!");
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
printf("Dwste nea dieuthinsi gia default\n");
SessionNewOpeningAddress(OpeningAddress,MySession);
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
case 14:
break;
}
}while(option);
return 0;}

How would you use a case to convert an enum to a string in C?

How would I go about making an enum into a string using a case such as
enum {Ace,....King} face;
to a case that would convert it to say "Ace" rather than a 0 or 1.
char const* faceToString(face f)
{
switch (f)
{
case Ace:
return "Ace";
case Two:
return "Two";
...
case King:
return "King"
}
}

Jumping from one case to the default case in switch statement

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;
}

Resources