switch quantity not an integer
Author |
Message |
gaius.petroni #1 / 23
|
 switch quantity not an integer
char *ptrhostname[BUFSIZ] ; char hostname[BUFSIZ]; /* * ptrhostname = (getenv("HOSTNAME")); */ /* const hostname = (char)* ptrhostname ; */ if(gethostname(hostname, BUFSIZ) < 0) perror("gethostname"); switch (hostname){ case "myhost.mydomain": { printf ("The hostname is %s\n", ... this is a Mandrake Linux 8.2 system the compiler error i am getting is main.c: In function `main': main.c:47: switch quantity not an integer main.c:48: case label does not reduce to an integer constant i am trying to figure out the logic in how why i would need to cast a unknown character string as an int. (this program is eventually going to run on about 10 machines and perform a "keepalive" of certain services based on the hostname.)
|
Fri, 11 Feb 2005 18:34:54 GMT |
|
 |
Joona I Palast #2 / 23
|
 switch quantity not an integer
Quote: > char *ptrhostname[BUFSIZ] ; > char hostname[BUFSIZ]; > /* * ptrhostname = (getenv("HOSTNAME")); */ > /* const hostname = (char)* ptrhostname ; */ > if(gethostname(hostname, BUFSIZ) < 0) > perror("gethostname"); > switch (hostname){ > case "myhost.mydomain": { > printf ("The hostname is %s\n", ... > this is a Mandrake Linux 8.2 system > the compiler error i am getting is > main.c: In function `main': > main.c:47: switch quantity not an integer > main.c:48: case label does not reduce to an integer constant > i am trying to figure out the logic in how why i would need to cast a > unknown character string as an int.
This is a misconception. For one thing, you do NOT need to cast the unknown character string as an int. For another, even if you did cast as an int, it would not help, as you would still get a compilation error. Quote: > (this program is eventually going to run on about 10 machines and > perform a "keepalive" of certain services based on the hostname.)
This is a basic limitation in the C language. The labels of case statements must be constants that are calculable at compile-time. String literals are not such contstants. You will have to do string comparison at run-time instead: if (strcmp(hostname, "myhost.mydomain")==0) { printf("The hostname is %s\n", ... Quote: }
--
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++| | http://www.helsinki.fi/~palaste W++ B OP+ | \----------------------------------------- Finland rules! ------------/ "And according to Occam's Toothbrush, we only need to optimise the most frequent instructions." - Teemu Kerola
|
Fri, 11 Feb 2005 18:43:56 GMT |
|
 |
willem veenhove #3 / 23
|
 switch quantity not an integer
Quote:
> switch (hostname){ > case "myhost.mydomain": { > printf ("The hostname is %s\n", ... > the compiler error i am getting is > main.c: In function `main': > main.c:47: switch quantity not an integer > main.c:48: case label does not reduce to an integer constant > i am trying to figure out the logic in how why i would need > to cast a unknown character string as an int.
3.6.4.2 The switch statement Constraints The controlling expression of a switch statement shall have integral type. The expression of each case label shall be an integral constant expression. So you simply can't use a string as a case label. willem
|
Fri, 11 Feb 2005 18:53:20 GMT |
|
 |
Richard Heathfiel #4 / 23
|
 switch quantity not an integer
Quote:
> > char *ptrhostname[BUFSIZ] ; > > char hostname[BUFSIZ]; > > /* * ptrhostname = (getenv("HOSTNAME")); */ > > /* const hostname = (char)* ptrhostname ; */ > > if(gethostname(hostname, BUFSIZ) < 0) > > perror("gethostname"); > > switch (hostname){ > > case "myhost.mydomain": { > > printf ("The hostname is %s\n", ... > > this is a Mandrake Linux 8.2 system > > the compiler error i am getting is > > main.c: In function `main': > > main.c:47: switch quantity not an integer > > main.c:48: case label does not reduce to an integer constant > > i am trying to figure out the logic in how why i would need to cast a > > unknown character string as an int. > This is a misconception. For one thing, you do NOT need to cast the > unknown character string as an int. For another, even if you did cast > as an int, it would not help, as you would still get a compilation > error.
Not necessarily, if he's talking about casting the switch thingy: switch((int)x). After all, using a string literal in a value context means that you get a pointer, and you're allowed to convert pointers into integers (not necessarily meaningfully, of course). Of course, it still won't help, as you rightly say. Quote: > > (this program is eventually going to run on about 10 machines and > > perform a "keepalive" of certain services based on the hostname.) > This is a basic limitation in the C language.
Well, I suppose you could think of it like that. :-) Quote: > The labels of case > statements must be constants that are calculable at compile-time. > String literals are not such contstants.
Very true. Quote: > You will have to do string comparison at run-time instead: > if (strcmp(hostname, "myhost.mydomain")==0) { > printf("The hostname is %s\n", ...
No, he doesn't *have* to do that. He could, for example, use a hashing algorithm which takes a string as input and which produces an int on which he can then switch. --
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999. C FAQ: http://www.eskimo.com/~scs/C-faq/top.html K&R answers, C books, etc: http://users.powernet.co.uk/eton
|
Fri, 11 Feb 2005 20:15:55 GMT |
|
 |
Eric Sosma #5 / 23
|
 switch quantity not an integer
Quote:
> the compiler error i am getting is > main.c: In function `main': > main.c:47: switch quantity not an integer > main.c:48: case label does not reduce to an integer constant
This is Question 20.17 in the comp.lang.c Frequently Asked Questions (FAQ) list http://www.eskimo.com/~scs/C-faq/top.html --
|
Fri, 11 Feb 2005 23:26:02 GMT |
|
 |
Morris Dove #6 / 23
|
 switch quantity not an integer
Quote: > char *ptrhostname[BUFSIZ] ; > char hostname[BUFSIZ]; > /* * ptrhostname = (getenv("HOSTNAME")); */ > /* const hostname = (char)* ptrhostname ; */ > if(gethostname(hostname, BUFSIZ) < 0) > perror("gethostname"); > switch (hostname){ > case "myhost.mydomain": { > printf ("The hostname is %s\n", ...
Gaius... You might consider setting up an array of filenames to search in a loop (using strcmp or friend) - then you can use the index of the matching array entry as the case value to match in a switch statement. HTH Morris Dovey West Des Moines, Iowa USA
|
Sat, 12 Feb 2005 00:57:32 GMT |
|
 |
Lew Pitch #7 / 23
|
 switch quantity not an integer
On Mon, 26 Aug 2002 11:57:32 -0500, in comp.lang.c, "Morris Dovey" Quote:
>> char *ptrhostname[BUFSIZ] ; >> char hostname[BUFSIZ]; >> /* * ptrhostname = (getenv("HOSTNAME")); */ >> /* const hostname = (char)* ptrhostname ; */ >> if(gethostname(hostname, BUFSIZ) < 0) >> perror("gethostname"); >> switch (hostname){ >> case "myhost.mydomain": { >> printf ("The hostname is %s\n", ... >Gaius... >You might consider setting up an array of filenames to search in a loop >(using strcmp or friend) - then you can use the index of the matching array >entry as the case value to match in a switch statement.
If there's a lot of this sort of parsing going on, the OP might consider using a variadic function to prepare his case values for the switch statement. Sort of like... /* sample code - not guaranteed to be 100% C standard */ #include <stdio.h> #include <stdarg.h> #include <string.h> /* compare sample string to list of strings; ** return index (0 to INT_MAX) of matching string ** or -1 if no match found */ int StringCase(char *sample, ... ) { va_list cp; char *model; int casenumber = 0; va_start(cp,sample); for (model=va_arg(cp,char *); model!=NULL;model=va_arg(cp,char *)) { if (strcmp(sample,model) == 0) return casenumber; else ++casenumber; } va_end(ap); return -1; /* sentinal to say "element not found" */ Quote: }
/* sample use of variadic function ** look through arguments for the strings ** "test", "joke", and "what.ever" */ int main(int argc, char **argv) { while (--argc) { switch(StringCase(*++argv,"test", "joke", "what.ever",NULL)) { case 0: /* argument was "test" */ printf("Found the word \"test\"\n"); break; case 1: /* argument was "joke" */ printf("Found the word \"test\"\n"); break; case 2: /* argument was "what.ever" */ printf("Found the phrase \"what ever\"\n"); break; default: /* unknown */ printf("I dont know the word \"%s\"\n",*argv); break; } } return 0; Quote: }
Lew Pitcher, Information Technology Consultant, Toronto Dominion Bank Financial Group
(Opinions expressed are my own, not my employer's.)
|
Sat, 12 Feb 2005 02:12:24 GMT |
|
 |
Dann Corbi #8 / 23
|
 switch quantity not an integer
Generic notion: Create a perfect hash for whatever you want to switch on. Switch on the hash. -- C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html "The C-FAQ Book" ISBN 0-201-84519-9 C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm
|
Sat, 12 Feb 2005 02:45:35 GMT |
|
 |
Kamilc #9 / 23
|
 switch quantity not an integer
If you like the 'clean look' of a switch statement, and are stymied by the fact that it only works on integers, you could do something like this: #include <stdio.h> #include <string.h> #define MATCHSTART if (0) { #define MATCH(a, b) } else if (strcmp((a), (b)) == 0) { #define MATCHSTOP } int main(void) { int i; char s[80]; char *s1 = "This is phrase 1."; char *s2 = "This is phrase 2."; char *s3 = "This is phrase 3."; for (i = 1; i <= 3; i++) { sprintf(s, "This is phrase %d.", i ); MATCHSTART MATCH (s, s1) printf("You matched phrase 1.\n"); printf("End of test 1.\n"); MATCH (s, s2) printf("You matched phrase 2.\n"); printf("End of test 2.\n"); MATCH (s, s3) printf("You matched phrase 3.\n"); printf("End of test 3.\n"); MATCHSTOP } Quote: }
|
Sat, 12 Feb 2005 04:17:15 GMT |
|
 |
Mark McIntyr #10 / 23
|
 switch quantity not an integer
Quote:
>the compiler error i am getting is >main.c: In function `main': >main.c:47: switch quantity not an integer
This error message says it all. The cases of a switch must be integer values, unlike other languages which allow you to switch on strings or other variable types. To do what you want, I would use strcmp and if... else... -- Mark McIntyre CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html> CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
|
Sat, 12 Feb 2005 07:23:03 GMT |
|
 |
Dan P #11 / 23
|
 switch quantity not an integer
Quote: >If you like the 'clean look' of a switch statement, and are stymied by >the fact that it only works on integers, you could do something like >this: >#include <stdio.h> >#include <string.h> >#define MATCHSTART if (0) { >#define MATCH(a, b) } else if (strcmp((a), (b)) == 0) { >#define MATCHSTOP } >int main(void) >{ > int i; > char s[80]; > char *s1 = "This is phrase 1."; > char *s2 = "This is phrase 2."; > char *s3 = "This is phrase 3."; > for (i = 1; i <= 3; i++) > { > sprintf(s, "This is phrase %d.", i ); > MATCHSTART > MATCH (s, s1) > printf("You matched phrase 1.\n"); > printf("End of test 1.\n"); > MATCH (s, s2) > printf("You matched phrase 2.\n"); > printf("End of test 2.\n"); > MATCH (s, s3) > printf("You matched phrase 3.\n"); > printf("End of test 3.\n"); > MATCHSTOP > } >}
Using the preprocessor to alter the language syntax is considered an abuse and it is a very bad idea. If you don't see why, try to find a copy of the original implementation of the Bourne shell (hint: it included a header named algol.h). Dan -- Dan Pop DESY Zeuthen, RZ group
|
Sat, 12 Feb 2005 21:05:11 GMT |
|
 |
David Resni #12 / 23
|
 switch quantity not an integer
Quote:
> Generic notion: > Create a perfect hash for whatever you want to switch on. > Switch on the hash.
Coming up with perfect hash (by which I assume you mean no collisions) is more trouble that it is worth. When adding a new entry, you must test it for uniqueness, as it was only "perfect" for the previously known set of input. And how do you use the hash? I assume you precompute it for all strings you care about and put them into a table corresponding to the things you care about (since the cases must be constant integer expressions). Why not just an enum and a table to match it to its string equivilant, and just a linear search through it? I assume there won't be a huge number of these, and this will be simpler. Example (uncompiled, untested): enum ip_addresses { myhost_mydomain, tortellini_mit_edu Quote: };
static struct address_pair { const char *text; enum ip_addresses enum_val; Quote: } addresses[] = {
{ "myhost.mydomain", myhost_mydomain }, { "tortellini.mit.edu", tortellini_mit_edu } Quote: };
Then have a function to get the enum value from the string, and switch on its return. Or, as others said, just have a series of strcmps... -David
|
Sat, 12 Feb 2005 22:00:04 GMT |
|
 |
Robert Stankowi #13 / 23
|
 switch quantity not an integer
Quote: > char *ptrhostname[BUFSIZ] ; > char hostname[BUFSIZ]; > /* * ptrhostname = (getenv("HOSTNAME")); */ > /* const hostname = (char)* ptrhostname ; */ > if(gethostname(hostname, BUFSIZ) < 0) > perror("gethostname"); > switch (hostname){ > case "myhost.mydomain": { > printf ("The hostname is %s\n", ... > this is a Mandrake Linux 8.2 system > the compiler error i am getting is > main.c: In function `main': > main.c:47: switch quantity not an integer > main.c:48: case label does not reduce to an integer constant > i am trying to figure out the logic in how why i would need to cast a > unknown character string as an int. > (this program is eventually going to run on about 10 machines and > perform a "keepalive" of certain services based on the hostname.)
<slightly OT> gaius, in addition to what others have said about the technical aspect: I'd recommend you rethink your approach. Seemingly you are going to hardcode a bunch of 10 or so hostnames into your program and to call different functions depending on which host you actually are. IMO this is a Bad Idea(TM). What if you want to add a host to your list, what if a hostname is changed by the sysadmin for some reason? (just two of a whole list of possibilities). Why not put the services which must be "kept alive" into a configuration file? this could be simply a list of integers, one for each service, and in your program you could, for example, use an array of function pointers to call the appropriate functions depending on the content of the configfile. </slightly OT> just my $0.02 Cheers Robert
|
Sat, 12 Feb 2005 22:53:24 GMT |
|
 |
Dann Corbi #14 / 23
|
 switch quantity not an integer
Quote: > > Generic notion: > > Create a perfect hash for whatever you want to switch on. > > Switch on the hash. > Coming up with perfect hash (by which I assume you mean no collisions) > is more trouble that it is worth.
Coming up with a perfect hash is as easy as falling off of a log. http://burtleburtle.net/bob/hash/perfect.html http://www.cs.wustl.edu/~schmidt/PDF/gperf.pdf http://www.amk.ca/python/code/perfect-hash.html http://www.amk.ca/python/code/perfect-hash.html http://eprints.cs.vt.edu:8080/archive/00000248/ I'll wager you have not looked at the subject much in the last ten years. [snip] -- C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html "The C-FAQ Book" ISBN 0-201-84519-9 C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm
|
Sun, 13 Feb 2005 01:40:07 GMT |
|
 |
gaius.petroni #15 / 23
|
 switch quantity not an integer
Quote:
> gaius, > in addition to what others have said about the technical aspect: > I'd recommend you rethink your approach. Seemingly you are going to hardcode > a bunch of 10 or so hostnames into your program and to call different > functions depending on which host you actually are. IMO this is a Bad > Idea(TM). What if you want to add a host to your list, what if a hostname is > changed by the sysadmin for some reason? (just two of a whole list of > possibilities). > Why not put the services which must be "kept alive" into a configuration > file? this could be simply a list of integers, one for each service, and in > your program you could, for example, use an array of function pointers to > call the appropriate functions depending on the content of the configfile. > </slightly OT> > just my $0.02 > Cheers > Robert
of course this would be the *right* way to do things, right? instead of imitating wInDoZe programmers and hardcoding everything like a fool. yes, i will do this. i have a few questions please: - do i read the list in the file using fgets and then at each newline execute the commands to test for the service status? - is there a simple way to ensure that a process is actually running properly? i have seen smbd and named return status (PID) and "running..." from the UNIX commandline, but in fact they were *dead.* is there a way to actually *prove* that the service is alive? (a generic method for all services i mean) ...*or*... is there a way to execute a command to probe the port and test the response, as i might do a telnet to port 80 and see if there is a response ...? can anyone provide some code example for this please? - how difficult would it be to have this run in a 'respawn' mode? what is required in the program for it to be able to respawn please? - should i allow for a configuration override?
|
Sun, 13 Feb 2005 13:34:18 GMT |
|
|
Page 1 of 2
|
[ 23 post ] |
|
Go to page:
[1]
[2] |
|