pointer arithmetic error?

Discussion in 'C Programming' started by Bill Cunningham, Dec 4, 2009.

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


    ---
    In C there should be no or little need for casts

    --Rihard Heathfield
    Bill Cunningham, Dec 4, 2009
    #1
    1. Advertising

  2. Bill Cunningham

    Lew Pitcher Guest

    On December 4, 2009 15:40, in comp.lang.c, Bill Cunningham
    () wrote:

    > 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. ------
    Lew Pitcher, Dec 4, 2009
    #2
    1. Advertising

  3. "Lew Pitcher" <> wrote in message
    news:cfc8a$4b19771c$cef882ed$-Free...

    > 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
    Bill Cunningham, Dec 5, 2009
    #3
  4. "Bill Cunningham" <> writes:
    > "Lew Pitcher" <> wrote in message
    > news:cfc8a$4b19771c$cef882ed$-Free...
    >
    >> 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.)

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, Dec 5, 2009
    #4
  5. "Keith Thompson" <> wrote in message
    news:...

    > 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
    ---
    In C there should be no or little need for casts

    --Richard Heathfield
    Bill Cunningham, Dec 5, 2009
    #5
  6. "Bill Cunningham" <> writes:

    > "Keith Thompson" <> wrote in message
    > news:...
    >
    >> 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.
    Ben Bacarisse, Dec 5, 2009
    #6
  7. On 5 Dec, 03:40, "Bill Cunningham" <> wrote:
    > "Keith Thompson" <> wrote in message
    > news:...


    > > 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')
    Nick Keighley, Dec 5, 2009
    #7
  8. "Nick Keighley" <> wrote in message
    news:...
    On 5 Dec, 03:40, "Bill Cunningham" <> wrote:
    > "Keith Thompson" <> wrote in message
    > news:...


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

    --
    In C there should be no or little need for casts

    --Richard Heathfield
    Bill Cunningham, Dec 5, 2009
    #8
  9. "Nick Keighley" <> wrote in message
    news:...

    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

    --
    In C there should be no or little need for casts

    --Richard Heathfield
    Bill Cunningham, Dec 5, 2009
    #9
  10. "Bill Cunningham" <> wrote in message
    news:4b1a9943$0$5330$...
    >
    > "Nick Keighley" <> wrote in message
    > news:...
    >
    > 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
    >
    > --
    > In C there should be no or little need for casts
    >
    > --Richard Heathfield
    >
    >
    >
    Bill Cunningham, Dec 5, 2009
    #10
  11. On 5 Dec, 17:20, Richard <> wrote:
    > Nick Keighley <> writes:


    <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')
    Nick Keighley, Dec 5, 2009
    #11
  12. On 5 Dec, 17:24, "Bill Cunningham" <> wrote:
    > "Nick Keighley" <> wrote in message
    > news:...
    > On 5 Dec, 03:40, "Bill Cunningham" <> wrote:
    > > "Keith Thompson" <> wrote in message
    > >news:...


    <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
    Nick Keighley, Dec 5, 2009
    #12
  13. "Nick Keighley" <> wrote in message
    news:...
    On 5 Dec, 17:24, "Bill Cunningham" <> wrote:
    > "Nick Keighley" <> wrote in message
    > news:...
    > On 5 Dec, 03:40, "Bill Cunningham" <> wrote:
    > > "Keith Thompson" <> wrote in message
    > >news:...


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

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

    Bill
    --
    In C there should be no or little need for casts

    --Richard Heathfield
    Bill Cunningham, Dec 5, 2009
    #13
  14. Did I screw up again?

    B
    Bill Cunningham, Dec 5, 2009
    #14
  15. "Thomas Stegen" <> wrote in message
    news:...

    > 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

    --
    In C there should be no or little need for casts

    --Richard Heathfield
    Bill Cunningham, Dec 5, 2009
    #15
  16. On 6 Dec 2009 at 7:19, Richard wrote:
    > Wouldn't numBeers be so much more readable?


    Readable isn't often a word that springs to mind to describe a name in
    camelcase.
    Antoninus Twink, Dec 6, 2009
    #16
  17. On 6 Dec, 07:19, Richard <> wrote:
    > Nick Keighley <> writes:
    > > On 5 Dec, 17:20, Richard <> wrote:
    > >> Nick Keighley <> writes:

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

    >
    > 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.
    Nick Keighley, Dec 6, 2009
    #17
  18. On 6 Dec, 10:41, Antoninus Twink <> wrote:
    > On  6 Dec 2009 at  7:19, Richard wrote:
    >
    > > Wouldn't numBeers be so much more readable?

    >
    > Readable isn't often a word that springs to mind to describe a name in
    > camelcase.


    I use source bases that use both. You can get used to either.
    Nick Keighley, Dec 6, 2009
    #18
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. a

    pointer arithmetic

    a, Sep 11, 2003, in forum: C++
    Replies:
    6
    Views:
    514
  2. Marc Schellens

    Iterator/pointer arithmetic

    Marc Schellens, Dec 5, 2003, in forum: C++
    Replies:
    15
    Views:
    836
    tom_usenet
    Dec 8, 2003
  3. dan

    Pointer arithmetic

    dan, Jan 6, 2004, in forum: C++
    Replies:
    1
    Views:
    352
    Jeff Schwab
    Jan 6, 2004
  4. ceo
    Replies:
    8
    Views:
    346
    Pete Becker
    Mar 10, 2005
  5. joshc
    Replies:
    5
    Views:
    544
    Keith Thompson
    Mar 31, 2005
Loading...

Share This Page