But I was going to try it through pointer arithmetic.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
int main(int argc, char *argv[])
{
if (argc > 4 || argc == 0) {
fprintf(stderr, "dice usage error\n");
exit(EXIT_FAILURE);
}
int c, d, x, y;
char **ptr = &argv[1];
x = strtol(argv[2], NULL, 10);
y = strtol(argv[3], NULL, 10);
if (*(ptr) || *(ptr + 1) == 'a') {
printf("%i\n", x + y);
exit(0);
}
di.c: In function `main':
di.c:16: warning: comparison between pointer and integer
di.c:19: error: syntax error at end of input
Errors from running gcc -c di.c
Bill
---
In C there should be no or little need for casts
--Rihard Heathfield
> I am creating a dice game that returns ints up to the number specified
> by argv[1]. Simple enough. But I am also wanting to add a switch, "-a" to
> be able to run a routine that adds two numbers and returns the result. So
> I want the program to accept "-a" or "a" or "a-" as the switch. Which
> would be *(argv[1]) *(argv[1]+1) or *(argv[1]+2) that I would need C to
> examine. Or
> argv[1][0] argv[1][1] argv[1][2].
>
> But I was going to try it through pointer arithmetic.
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <ctype.h>
> #include <time.h>
>
> int main(int argc, char *argv[])
> {
> if (argc > 4 || argc == 0) {
> fprintf(stderr, "dice usage error\n");
> exit(EXIT_FAILURE);
> }
> int c, d, x, y;
> char **ptr = &argv[1];
> x = strtol(argv[2], NULL, 10);
> y = strtol(argv[3], NULL, 10);
> if (*(ptr) || *(ptr + 1) == 'a') {
OK, Bill. Above is line 16, the origin of the "comparison between pointer
and integer" warning.
Do we agree that <ptr> is a pointer to a pointer to char? Yes?
So <*(ptr)> is a pointer to char, right? We dereference a pointer to
pointer, to get a pointer.
And < *(ptr + 1) > is also a pointer to char, right? We add 1 to <ptr>,
getting another "pointer to a pointer to char", then dereference it to get
a "pointer to char".
But, what of <'a'>? What type of data is it? Of course, <'a'> is an integer
constant.
Now, in line 16, you compare
a pointer to char
with
an integer constant
but, of course, these two things have different types, and cannot be
compared with any meaning.
Hence the warning message.
> printf("%i\n", x + y);
> exit(0);
> }
Above is line 19. The line contains the closing brace of a compound
statement, and that brace matches the opening brace on line 16.
There is one other compound statement that is still open at this point: the
compound statement that started on line 7 (the 'body' statement of the
main() function).
Presumably, your source file ends here. Since no closing brace (to match the
opening brace on line 7) has been found by the end of the source file, the
compiler complains that you have a syntax error.
> di.c: In function `main':
> di.c:16: warning: comparison between pointer and integer
> di.c:19: error: syntax error at end of input
>
> Errors from running gcc -c di.c
>
> Bill
>
>
> ---
> In C there should be no or little need for casts
>
> --Rihard Heathfield
>
>
--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
Me: http://pitcher.digitalfreehold.ca/ | Just Linux: http://justlinux.ca/
---------- Slackware - Because I know what I'm doing. ------
> But, what of <'a'>? What type of data is it? Of course, <'a'> is an
> integer
> constant.
[snip]
'a' is what is supposed to be in argv[1]. So I would think it would be a
char* or char**. To be more precise I want it in argv[1][1] or argv[1][0] is
acceptable. The code as you correctly noticed is a fragment. From the
command line if -a or a is entered as argv[1] I would use x and y total the
values for argv[3] and argv[4].
I'm not quite seeing where you say a is an int. I got to learn this
sometime.
Bill
---
In C there should be no or little need for casts
--Richard Heathfield
No.
argv is a char**, so argv[1] is of type char*.
> So I would think it would be a
> char* or char**.
Why would you think that? How could 'a' be of type char* or char**?
I can understand thinking that 'a' is of type char. For historical
reasons, character constants such as 'a' are of type int, not of type
char. It could make sense to compare a character constant to
something of type char.
> To be more precise I want it in argv[1][1] or argv[1][0] is
> acceptable.
That's not more precise, that's just different.
argv is of type char**. argv[1] is of type char*. argv[1][1] is of
type char. Three different types, none of which are in any way
compatible with each other.
> The code as you correctly noticed is a fragment.
The only thing that kept it from being a complete program was the
closing "}" for main.
> From the
> command line if -a or a is entered as argv[1] I would use x and y total the
> values for argv[3] and argv[4].
>
> I'm not quite seeing where you say a is an int. I got to learn this
> sometime.
There's nothing in your program named a. 'a', the character constant,
is of type int. (a is an identifier; 'a' is a character constant.
This is not a trivial difference.)
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
> I can understand thinking that 'a' is of type char. For historical
> reasons, character constants such as 'a' are of type int, not of type
> char. It could make sense to compare a character constant to
> something of type char.
>
>> To be more precise I want it in argv[1][1] or argv[1][0]
>> is
>> acceptable.
>
> That's not more precise, that's just different.
>
> argv is of type char**. argv[1] is of type char*. argv[1][1] is of
> type char. Three different types, none of which are in any way
> compatible with each other.
>
>> The code as you correctly noticed is a fragment.
>
> The only thing that kept it from being a complete program was the
> closing "}" for main.
>
>> From the
>> command line if -a or a is entered as argv[1] I would use x and y total
>> the
>> values for argv[3] and argv[4].
>>
>> I'm not quite seeing where you say a is an int. I got to learn this
>> sometime.
>
> There's nothing in your program named a. 'a', the character constant,
> is of type int. (a is an identifier; 'a' is a character constant.
> This is not a trivial difference.)
So what should I do? I thought 'a' meant character. Cast? I don't think
that would be the right thing to do. Should I use some kind of conversion
function? I'm stumped on this one.
The fact that the types are wrong is just showing you that you have
not found the right thing to compare equal to 'a'. argv is of type
char ** and argv[1] is of type char *. When your program is called
with argv[1] pointing at "-a" then argv[1][0] == '-' and argv[1][1] ==
'a'. Alternatively you can test to see of strcmp(argv[1], "-a") == 0.
> ---
This is not a good sig separator. The accepted standard is "-- "
(note the space after the two dashes).
--
Ben.
> > I can understand thinking that 'a' is of type char. For historical
> > reasons, character constants such as 'a' are of type int, not of type
> > char. It could make sense to compare a character constant to
> > something of type char.
note well.
> >> To be more precise I want it in argv[1][1] or argv[1][0]
> >> is acceptable.
>
> > That's not more precise, that's just different.
>
> > argv is of type char**. argv[1] is of type char*. argv[1][1] is of
> > type char. Three different types, none of which are in any way
> > compatible with each other.
did you follow that?
> >> The code as you correctly noticed is a fragment.
>
> > The only thing that kept it from being a complete program was the
> > closing "}" for main.
>
> >> From the
> >> command line if -a or a is entered as argv[1] I would use x and y total
> >> the
> >> values for argv[3] and argv[4].
>
> >> I'm not quite seeing where you say a is an int. I got to learn this
> >> sometime.
>
> > There's nothing in your program named a. 'a', the character constant,
> > is of type int. (a is an identifier; 'a' is a character constant.
> > This is not a trivial difference.)
>
> So what should I do? I thought 'a' meant character.
yes 'a' is character constant (ignore for the time being that it is of
type int) and can be compared with a char.
char c;
if (c == 'a')
is perfectly ok (assuming c has a sensible value in it). You are
trying to compare a char constant with a POINTER-TO-CHAR. THis is not
valid
char *pc;
if (pc == 'a')
this is NOT ok
> Cast? I don't think
> that would be the right thing to do. Should I use some kind of conversion
> function? I'm stumped on this one.
explain what you are trying to do.
Would this do what you want?
if (argv[1][0] == 'a')
Why not just say 'a' is a character for God's sake?
>
> is perfectly ok (assuming c has a sensible value in it). You are
> trying to compare a char constant with a POINTER-TO-CHAR. THis is not
> valid
>
> char *pc;
> if (pc == 'a')
>
> this is NOT ok
>
>> Cast? I don't think
>> that would be the right thing to do. Should I use some kind of conversion
>> function? I'm stumped on this one.
>
> explain what you are trying to do.
>
> Would this do what you want?
>
> if (argv[1][0] == 'a')
>
The first thing to do with non-trolls is to move away from argv.
e.g char * ptrToCharArg=argv[1];
etc etc etc
--
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c
> > I can understand thinking that 'a' is of type char. For historical
> > reasons, character constants such as 'a' are of type int, not of type
> > char. It could make sense to compare a character constant to
> > something of type char.
note well.
> >> To be more precise I want it in argv[1][1] or argv[1][0]
> >> is acceptable.
>
> > That's not more precise, that's just different.
>
> > argv is of type char**. argv[1] is of type char*. argv[1][1] is of
> > type char. Three different types, none of which are in any way
> > compatible with each other.
did you follow that?
I think.
> >> The code as you correctly noticed is a fragment.
>
> > The only thing that kept it from being a complete program was the
> > closing "}" for main.
>
> >> From the
> >> command line if -a or a is entered as argv[1] I would use x and y total
> >> the
> >> values for argv[3] and argv[4].
>
> >> I'm not quite seeing where you say a is an int. I got to learn this
> >> sometime.
>
> > There's nothing in your program named a. 'a', the character constant,
> > is of type int. (a is an identifier; 'a' is a character constant.
> > This is not a trivial difference.)
>
> So what should I do? I thought 'a' meant character.
yes 'a' is character constant (ignore for the time being that it is of
type int) and can be compared with a char.
char c;
if (c == 'a')
Ok but that wouldn't work with two characters. For example this I know
wouldn't work:
char c;
if( c=="-a")
Because it's a string. I was going to try my hand at pointer arithmetic and
look at argv[1][0] and argv[1][1].
is perfectly ok (assuming c has a sensible value in it). You are
trying to compare a char constant with a POINTER-TO-CHAR. THis is not
valid
char *pc;
if (pc == 'a')
this is NOT ok
> Cast? I don't think
> that would be the right thing to do. Should I use some kind of conversion
> function? I'm stumped on this one.
explain what you are trying to do.
Would this do what you want?
if (argv[1][0] == 'a')
The program dice.exe would be called from DOS or windows command by dice -a
4 5 and the result would be 9. Now it should also do this as a number
generator:
dice 6 //would give randoms up to 6.
dice 12 //would give randoms up to 12.
Bill
Would this do what you want?
if (argv[1][0] == 'a')
Yes that would work. I was trying to attempt this via this way. Maybe it
doesn't work that way.
*(argv[1]) and *(argv[1]+1) which would a pointers to argv[1][0] and
argv[1][1].
Bill
Wait more what I woant come to think of it is
if (argv[1][0]=='-' && argv[1][1]=='a')
<snip>
> > Would this do what you want?
>
> > if (argv[1][0] == 'a')
>
> The first thing to do with non-trolls is to move away from argv.
>
> e.g char * ptrToCharArg=argv[1];
I usually call it arg
char *arg = argv[1];
if (arg[0] == 'a')
<snip>
> > >> To be more precise I want it in argv[1][1] or argv[1][0]
> > >> is acceptable.
>
> > > That's not more precise, that's just different.
>
> > > argv is of type char**. argv[1] is of type char*. argv[1][1] is of
> > > type char. Three different types, none of which are in any way
> > > compatible with each other.
>
> did you follow that?
you fucked up the quoting again.
> I think.
<snip>
> > So what should I do? I thought 'a' meant character.
>
> yes 'a' is character constant (ignore for the time being that it is of
> type int) and can be compared with a char.
>
> char c;
> if (c == 'a')
>
> Ok but that wouldn't work with two characters. For example this I know
> wouldn't work:
>
> char c;
> if( c=="-a")
>
> Because it's a string.
yup. Use strcmp() tocompare strings
> I was going to try my hand at pointer arithmetic and
> look at argv[1][0] and argv[1][1].
which are of what type?
<snip>
> explain what you are trying to do.
<snip>
> The program dice.exe would be called from DOS or windows command by dice -a
> 4 5 and the result would be 9. Now it should also do this as a number
> generator:
>
> dice 6 //would give randoms up to 6.
> dice 12 //would give randoms up to 12.
ok. Write a program to do that. You have the pieces
<snip>
> I think.
<snip>
<snip>
I think argv[1][0] would be char ** right?
B
>
>> I was going to try my hand at pointer arithmetic and
>> look at argv[1][0] and argv[1][1].
>
> which are of what type?
>
> <snip>
>
> I think argv[1][0] would be char ** right?
>
I am afraid not. Cast you mind to your original declaration of main for
context: int main(int argc, char *argv[])
So step by step I will you give you some leading questions. I'll also
give you the answers, but please try to understand why I am asking these
questions and why the answers are what they are.
What type is argv?
argv is of type char**.
So what type must *argv be?
*argv is of type char*.
Do you understand that *argv is the same as argv[0]? This is a central
part of the puzzle.
Essentially *(argv + 0) is the same as argv[0] and *(argv + 1) is the
same as argv[1].
Now, maybe take a break and digest all that. No point in moving on until
you get it :)
So now that we are ready to move on, what type is **argv?
It is of type char.
Remember how *(argv + 1) is the same as argv[1]? So *(*(argv + 1) + 0)
is the same as argv[1][0]?
Notice how each steps dereferences one step so to speak.
So argv[1][0] is of what type? Hint: the answer is above.
--
Thomas.
Come to think of it, I would think so too :)
--
Thomas.
> So argv[1][0] is of what type? Hint: the answer is above.
char right? I was getting confused I think because I know argv[] *can*
be the same as a pointer and can be treated like one. In other words char *.
And also there is a char * before argv[] so I was thinking char ** but I
guess it would be char when done with pointers.
Bad.
For something as simple as this call it what it is.
It would otherwise be like calling an integer that holds the number of
bottles of beer something like "myint".
Wouldn't numBeers be so much more readable?
Readable isn't often a word that springs to mind to describe a name in
camelcase.
Horses for (or should that be Camels) for courses. I personally find it
very readable. The nature of the upper case at word boundaries makes it
pretty obvious immediately where the names components are.
it's the current argument being processed. ptrToCharArg looks a bit
hungarian to me, I don't encode the type in the identifier.
I use source bases that use both. You can get used to either.