Hi,
A simple question: In ANSI-C, how to specify a string as the expression
for switch statement.
eg
switch (mystr) {
case "ABC" : bleh...
break;
case "DEF" : bleh
break'
default: bleh;
break;
}
AFAIK, the expression must produce an integer value. In the case of a
string, what is the work-around?
Aaron 21 7719
Q: How do I switch on strings?
The simple answers are:
a) don't use switch. use if/else with strcmp
b) make an array of possible strings and use a lookup function to
return the index of your string (or -1) and switch on that.
The most common time I face this sort of thing is parsing config files
for tokens. The approach I take is an enhancement to the simple answer
b) above, using a structure consisting of an enumeration of index
values associated with the string. The enum makes it handy to add new
keys without having to worry about index numbers as opposed to having
case 1:, case 2: to go update. Here's an example for a few strings:
typedef enum
{
eKEY_HOST = 0,
eKEY_PORT, /* implicitly = 1 ... etc */
eKEY_PROTO,
eNUM_KEYS, /* number of valid keys */
eKEY_INVALID
} cfg_key_names;
/* array of structures to map the enum (numerical) values to strings */
struct {
cfg_key_names id;
const char *str;
} cfg_keys[] = {
{ eKEY_HOST, "host" },
{ eKEY_PORT, "port" },
{ eKEY_PROTO, "proto" }
};
/* get the number of entries in the above array automatically */
int n_cfg_keys = sizeof(cfg_keys ) / sizeof(cfg_keys[0]);
/* lookup function */
int parse_cfg_key(c onst char *str)
{
int i;
for (i = 0; i < n_cfg_keys; i++)
if (strcmp(str, cfg_keys[i].str) == 0)
return cfg_keys[i].id;
return eKEY_INVALID;
}
switch (parse_cfg_key( some_str))
{
case eKEY_HOST:
/* ... */
break;
default:
case eKEY_INVALID:
/* NO STRING FOR YOU! */
break;
}
Hope that helps. aa******@yahoo. com.au said:
Hi,
A simple question: In ANSI-C, how to specify a string as the expression
for switch statement.
You can't, but keep reading, because there is a way around this.
eg
switch (mystr) {
case "ABC" : bleh...
break;
case "DEF" : bleh
break'
default: bleh;
break;
}
AFAIK, the expression must produce an integer value. In the case of a
string, what is the work-around?
Associate each string with an integer (a struct works well here), preferably
in a sorted container of some kind (sorted array, or BST, or hash table, or
something of the kind), to make retrieval quicker. Look up the string, find
the associated number, and switch on that instead.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
"typedef" <ty************ @gmail.comwrote :
Q: How do I switch on strings?
The simple answers are:
a) don't use switch. use if/else with strcmp
b) make an array of possible strings and use a lookup function to
return the index of your string (or -1) and switch on that.
c) Use a hash.
Richard
"typedef" <ty************ @gmail.comha scritto nel messaggio
news:11******** *************@i 12g2000cwa.goog legroups.com...
Q: How do I switch on strings?
The simple answers are:
a) don't use switch. use if/else with strcmp
b) make an array of possible strings and use a lookup function to
return the index of your string (or -1) and switch on that.
The most common time I face this sort of thing is parsing config files
for tokens. The approach I take is an enhancement to the simple answer
b) above, using a structure consisting of an enumeration of index
values associated with the string. The enum makes it handy to add new
keys without having to worry about index numbers as opposed to having
case 1:, case 2: to go update. Here's an example for a few strings:
typedef enum
{
eKEY_HOST = 0,
eKEY_PORT, /* implicitly = 1 ... etc */
eKEY_PROTO,
eNUM_KEYS, /* number of valid keys */
eKEY_INVALID
} cfg_key_names;
/* array of structures to map the enum (numerical) values to strings */
struct {
cfg_key_names id;
const char *str;
} cfg_keys[] = {
{ eKEY_HOST, "host" },
{ eKEY_PORT, "port" },
{ eKEY_PROTO, "proto" }
};
/* get the number of entries in the above array automatically */
int n_cfg_keys = sizeof(cfg_keys ) / sizeof(cfg_keys[0]);
And for checking:
char only_for_check[2 * (sizeof(cfg_key s) / sizeof(cfg_keys[0]) ==
eNUM_KEYS) - 1];
/*
* in this case "n_cfg_keys " is not necessary
*/
>
/* lookup function */
int parse_cfg_key(c onst char *str)
{
int i;
for (i = 0; i < n_cfg_keys; i++)
if (strcmp(str, cfg_keys[i].str) == 0)
return cfg_keys[i].id;
return eKEY_INVALID;
}
switch (parse_cfg_key( some_str))
{
case eKEY_HOST:
/* ... */
break;
default:
case eKEY_INVALID:
/* NO STRING FOR YOU! */
break;
}
If you have found the index, the work is done.
It is possible to add a function field to the
struct to avoid the switch.
x = parse_cfg_key(s ome_str);
if (x != eKEY_INVALID) {
(*cfg_keys[x].fun)(); /* or with arguments */
} else {
/* ... */
}
The "id" field is not necessary if you respect the order:
struct str_and_fun_onl y {
const char *str;
void (*fun)(void);
};
"parse_cfg_ key" can return directly 'i'.
--
Giorgio Silvestri
DSP/Embedded/Real Time OS Software Engineer
Richard Bos wrote:
"typedef" <ty************ @gmail.comwrote :
Q: How do I switch on strings?
The simple answers are:
a) don't use switch. use if/else with strcmp
b) make an array of possible strings and use a lookup function to
return the index of your string (or -1) and switch on that.
c) Use a hash.
Richard
That inspired an entry on The Daily WTF. I wouldn't recommend it
myself. aa******@yahoo. com.au wrote:
Hi,
A simple question: In ANSI-C, how to specify a string as the expression
for switch statement.
eg
switch (mystr) {
case "ABC" : bleh...
break;
case "DEF" : bleh
break'
default: bleh;
break;
}
AFAIK, the expression must produce an integer value. In the case of a
string, what is the work-around?
After 16 years, I've become an advocate for simplicity. Any workaround
that allows you to use a switch is just going to bog you down in extra
work and complexity, so I'd advocate ditching the switch statement
entirely and just going with
if (!strcmp(mystr, "ABC"))
{
/* do stuff */
}
else if (!strcmp(mystr, "DEF"))
{
/* do stuff */
}
...
else
{
/* do default */
}
John Bode said:
> aa******@yahoo. com.au wrote:
>Hi,
A simple question: In ANSI-C, how to specify a string as the expression for switch statement.
eg
switch (mystr) { case "ABC" : bleh... break; case "DEF" : bleh break' default: bleh; break; }
AFAIK, the expression must produce an integer value. In the case of a string, what is the work-around?
After 16 years, I've become an advocate for simplicity. Any workaround
that allows you to use a switch is just going to bog you down in extra
work and complexity, so I'd advocate ditching the switch statement
entirely and just going with
if (!strcmp(mystr, "ABC"))
{
/* do stuff */
}
else if (!strcmp(mystr, "DEF"))
{
/* do stuff */
}
...
else
{
/* do default */
}
That's a perfectly reasonable alternative, but what if you have a great many
cases? It's not a very scalable solution. You can, of course, use the
result of strcmp:
diff = strcmp(mystr, "MNO");
if(diff == 0)
{
/* whatever */
}
else if(diff < 0)
{
/* handle cases "AAA" to "MNN" */
diff = strcmp(mystr, "HIJ");
if(diff == 0) etc etc
}
else
{
/* handle cases "MNP" to "ZZZ" */
diff = strcmp(mystr, "RST");
if(diff == 0) etc etc
}
but really, if you have so many cases as to make this worth doing, you're
better off with a bunch of string/functionptr structs in a sorted array, a
tree, or a hashtable.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
<aa******@yahoo .com.auwrote in message
news:11******** **************@ 42g2000cwt.goog legroups.com...
Hi,
A simple question: In ANSI-C, how to specify a string as the expression
for switch statement.
eg
switch (mystr) {
case "ABC" : bleh...
break;
case "DEF" : bleh
break'
default: bleh;
break;
}
AFAIK, the expression must produce an integer value. In the case of a
string, what is the work-around?
You can't. Other posters have made great suggestions. I'll make more.
The disadvantage of else-if is of course that the execution time to match
one of the last clauses will be longest of all. Depends on how many you
have. I have a couple suggestions, all of which will get me boo'd on this
group.
#1
---
Make the compiler work for a living:
switch(mystr[0])
{
case 'A' :
{
switch (mystr[1])
{
//And nest arbitrarily deeply.
#2
---
Standard BSEARCH, with the table of strings ordered in the source code. You
can include a function pointer as part of the table. That, at least is
O(log N) rather than O(N). http://en.wikipedia.org/wiki/Bsearch
---------
The suggestions by the other posters involving hashing were of course very
good ... but BSEARCH seems easier and cleaner. For one thing, no hash
collisions to worrry about.
Dave.
David T. Ashley wrote:
<aa******@yahoo .com.auwrote in message
news:11******** **************@ 42g2000cwt.goog legroups.com...
Hi,
A simple question: In ANSI-C, how to specify a string as the expression
for switch statement.
You can't. Other posters have made great suggestions. I'll make more.
[...]
The suggestions by the other posters involving hashing were of course very
good ... but BSEARCH seems easier and cleaner. For one thing, no hash
collisions to worrry about.
If you use a hash function generator such as gperf, you have no hash
collisions to worry about either. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Myster Ious |
last post by:
Polymorphism replaces switch statements, making the code more
compact/readable/maintainable/OO whatever, fine!
What I understand, that needs to be done at the programming level, is
this:
a switch-case has a variable (most probably an enumeration) &
associated symbols or integral value. Selection is made, base on what
symbol/value the variable holds. So
|
by: Thomas Matthews |
last post by:
Hi,
My son is writing a program to move a character. He is
using the numbers on the keypad to indicate the direction
of movement:
7 8 9
4 5 6
1 2 3
Each number has a direction except for '5'. So in
his switch statement, he omits a case for '5':
|
by: Minti |
last post by:
I was reading some text and I came across the following snippet
switch('5')
{
int x = 123;
case '5':
printf("The value of x %d\n", x);
break;
}
|
by: Mark |
last post by:
Hi - how can I get a switch statement to look for a range of values?
I have:
function payCalc(field, field2)
switch(field.value)
{
case 0-50: field2.value="lower band";
case 51-99: field2.value="mid band";
case 100-9999: field2.value="high band";
|
by: pickedaname |
last post by:
I work for a telecom company.
We need to get data from our 5ESS switches to be consumed by a .NET app.
The data I am getting back is incomplete.
For example, the beginning of the first line recvd from the device should
read:
SWT5 5e16(2) 02.00
Instead I get
a bunch of gibberish then SWT5
| |
by: |
last post by:
Is it fine to call another method from Switch?
Eg.
Switch (stringVar)
{
case ("a"):
somVar = "whatever";
Another_Method(); //call another method
return;
|
by: ajba74 |
last post by:
Hi fellows,
I am reading some books to learn the C programming language, and
sometimes I have the feeling that when somebody becomes a C expert, he
must learn a more modern and object-oriented language.
When I read things like "... C++ is an evolution of C ..." or "... C
is a subset of C++ ..." I tend to believe that I will have to learn C+
+ sooner or later. It sounds like C++ is the future and C is the past
(and will be no longer...
|
by: Rohit |
last post by:
Hi,
I am working on a switch module which after reading voltage through a
port pin and caterogizing it into three ranges(open,low or high),
passes this range to a function switch_status() with parameters value
and signal ID. Signal Id is used to get a user configurable parameter
inside a configuration file, which depends on the type of switch.
I have implemented it as under. Please ignore those magic numbers as I
have mimized logic to...
|
by: Satya |
last post by:
Hi everyone,
This is the first time iam posting excuse me if iam making any
mistake. My question is iam using a switch case statement in which i
have around 100 case statements to compare. so just curious to find
out is it effective to use this method?? or is there is any other
alternative method present so that execution time and code size can be
reduced??
Thanks in advance.
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |