pointer arithmetic error?

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

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') {
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
 
L

Lew Pitcher

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.
 
B

Bill Cunningham

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
 
K

Keith Thompson

Bill Cunningham said:
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].

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.)
 
B

Bill Cunningham

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.

Bill
 
B

Ben Bacarisse

Bill Cunningham said:
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).
 
N

Nick Keighley

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 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')
 
B

Bill Cunningham

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 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
 
B

Bill Cunningham

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
 
B

Bill Cunningham

Bill Cunningham said:
Would this do what you want?

if (argv[1][0] == 'a')

Wait more what I woant come to think of it is

if (argv[1][0]=='-' && argv[1][1]=='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
 
N

Nick Keighley

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.


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?

explain what you are trying to do.

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
 
B

Bill Cunningham

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.


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>

I think argv[1][0] would be char ** right?

Bill
 
B

Bill Cunningham

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.

Bill
 
N

Nick Keighley

Nick Keighley said:
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')

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?- Hide quoted text -

it's the current argument being processed. ptrToCharArg looks a bit
hungarian to me, I don't encode the type in the identifier.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top