#switch()
14 messages in this thread
I'm having trouble using argv[1] as the controlling expression in switch().
Assume the command line entry is "program ee". Code as follows:
#include <stdio.h>
#include <string.h>
main(argc, argv)
int argc
char *argv[]
{ switch(*argv[1])
{ case 'ee': etc…….
Switch() seems only to see "e", not "ee". Is the single character a
limitation of switch() or am I describing argv[1] wrong?
Thanks for any help.
Rob, I believe switch() doesn't support char arrays (strings) as cases.
You'll have to use strcmp() or a similar string compare routine to do that.
Also, *argv[1] is a pointer to the first character in argv[1], i.e. the
switch() statement is only getting the first character of argv[1] into the
switch.
I'm sure someone will correct me if I'm wrong. 🙂
Khalid.
Well, I'm no expert, but I think you got it half right. I believe that the
switch statement is limited to either a type char or int (they're
essentially the same anyway) so strings are out.
On the argv[] portion, however, if you'll notice the declaration of argv (
*argv[] ) you can see that what is being set up is an array of pointers. So
in this case by dereferencing argv[1] you will get a pointer out of the
array. Knowing the type of information it represents lets you know that
statements of the type argv[1][0] will give you the first letter of the
first command line argument (since argv[0] returns the program name
itself).
Anyway, I noticed the name and I was wondering if you are the Khalid that
has written the requestor library? If you are, thanks. You have written
an extremely good program. I started using it just prior to getting a 3000
with WB2.0, so it doesn't get the workout now that it did before, but it is
a solid program nonetheless.
See Ya,
Bill
P.S. And if you aren't that Khalid, just ignore the previous comments 😉
– via Whap!
>I believe that the
>switch statement is limited to either a type char or int (they're essentially
>the same anyway) so strings are out.
The expression of a switch must be (allowing for conversion and promotion) an
integral type and hence the case labels must be integral constant expressions.
Integral gives us the option of the char, short, int, long, and enum range.
In an way it is a shame other additional types can't be added into that range.
Note some C compilers do not support the enum and long choices though.
Rob, What you're trying to do doesn't make sense to me. From K&R: Any
single character can be written between single quotes to produce a value
equal to the numerical value of the character in the machine's character
set; this is called a character constant. So, for example, 'A' is a
character constant; in the ASCII character set its value is 65, the
internal representation of the character A.
In otherwords, you're misusing the single quoting convention. I am
suprised that you're compiler didn't complain about this.
-sja
(I see that Rob's code has been addressed, but to take a tangent to keep this
conversation alive a bit more on part of the subject that's been brough up:)
>'A' is a character constant…. I am surprised that your compiler didn't
>complain about 'ee'
The deal with character constant is somewhat confusing. The deal is that
even though it is a *character* constant, it is of type *integer* in C
(in C++ is is indeed a char) and hence there was no complaint.
That is to say, sizeof('?') == sizeof(int). There are a few rarer cases
where doing this is useful, however they are so uncommon that compilers
should issue a warning (perhaps initiated by a compiler switch) if you code it.
Rob, My message to you assumed you didn't make a typo and _really_ meant
'ee'. If that was a typo and you meant case "ee":, see Khalid's reply.
Thanks, Khalid was right. My manual said switch() would take scalar
constants, which it never defined. I guess I should do a lookup table; I
was just being lazy and hoping. strcpy() and strcmp() will do the
conversion/comparison but seem to work differently (i.e. require slightly
different code) on my usual machines.
FWIW, the code compiled just fine and even worked when I was lucky enough
to test a single-character case with both Manx and whatever compiler Sun
4.1.1 uses.
Khalid, if you're reading this, case 'a': was for Awali 🙂
Rob, hehehe.. Awali? No kidding?! (grin)
Rob,
Your description of argv is correct; argv is an array of pointers to
char (strings), you find either yours or "char **argv". The problem is
that "*argv[1]" IS only a single character. If you're intention is to look
at the 'entire' string, then you want "argv[1]". Unfortunately, you
can't "switch" on a string (they are variable length, and switch only works
on things (scalars) of size less than or equal to LONG.
Ah-ha…now I see. No wonder you teach thistuff. Switch() choked when I
tried to feed it "argv[1]" but worked with the single character pointer.
The strcmp() and strcpy() way of calling a function from "argv" seems
inelegant. Care to suggest another way? What I'm trying to do is write a
prog like unix "man".
My suggestion would be to do the following:
1) Create a table which has a series of strings and constants:
struct TABLE { int value; char *string } look[] = {
{ 1, "option1"}, {2, "nopage"}, {3, "format"}, {4, "resize"} };
2) Write a routine that takes the string to compare and the based of the
table and searches for that string in the table. If found, it returns the
value associated with the string. Otherwise it returns an error.
3) In your main code, just switch on the value returned from this function.
The nice thing about this function is that you can teach it about
abbreviations without having to change any of your code.
John A. Toebes, VIII – via Whap!
As "arrays are not first class citizens" with the additional "then neither
are 'strings'", many situations will lent themselves to being a tad (or
more) burdensome. You can either go the route John suggests or bring
yourself into the world of C++ where it will let you create a string type
(the switch() would still expect an integral, but you could do some
conversion of various sorts). The other issue is that you will be
interrogating argv anyway, so you probably do want to distinctly check each
and every character in many cases, or perhaps make the switches distinct
enough.