confusion when comparing char * with a string literal

Discussion in 'C++' started by william, Mar 17, 2007.

  1. william

    william Guest

    #include <stdio.h>

    int main()
    {
    char *str=NULL;
    char x[]="today is good!";
    printf("%s", str);
    str=strtok(x," ");
    if (str=="today") //<==here is line that confuses me
    printf("they equals!\n");
    return 0;
    }

    I printed "str" first, and the console displayed "today". However,
    when I try to comapare 'str' with "today", the condition failed!

    Exactly speaking, I know that 'str' is a 4 byte pointer of char type,
    so it is not equal to a string. But even in the gdb, I used 'p str',
    it printed "today".

    So, my question is how do we compare arrays and char *(I found that it
    is so commonly used as string)?

    one more question: is it true that we have to initialize a char * or
    points it to somewhere in memory, or to malloc memory to it before we
    can use it?
    Because I got segfault several times arising from this problem too.

    Thank you for your reply in advance!

    Ji
    william, Mar 17, 2007
    #1
    1. Advertising

  2. william

    SasQ Guest

    Dnia Sat, 17 Mar 2007 12:01:03 -0700, william napisa³(a):

    > #include <stdio.h>


    In C++ it is #include <cstdio>

    > int main()
    > {
    > char *str=NULL;
    > char x[]="today is good!";
    > printf("%s", str);


    You're trying to print something pointed by a null pointer
    [a pointer that points to "nowhere"]. Accessing a null pointer
    in C++ is UB. It may crash, it my print "(null)", it may print
    some garbage or do nothing.

    > str=strtok(x," ");


    Now you're setting the pointer to the first token found by
    strtok. It doesn't point to nowhere until now. It points to
    a beginning of "today\0is good!\0"... [the strtok put the
    NUL character after first token "today"].

    > if (str=="today") //<==here is line that confuses me
    > printf("they equals!\n");
    > return 0;
    > }
    >
    > I printed "str" first, and the console displayed "today".


    For me it displays "(null)". And it's true, because the
    'str' pointer passed to the first printf is set to nowhere.

    > However, when I try to comapare 'str' with "today", the
    > condition failed!


    And it's proper behaviour, because you're comparing the
    pointers [not strings], and they point to different memory
    locations ;) So they're not equal.

    > Exactly speaking, I know that 'str' is a 4 byte pointer


    On some platforms ;)

    > of char type, so it is not equal to a string.


    What string? Do you mean that literal constant?

    > But even in the gdb, I used 'p str', it printed "today".


    And it's also OK, because 'str' points to a memory location,
    where "today" lays. But it's not the same "today" as the one
    you compare with ;P The first "today" is the part of the
    array x, and the second is the literal constant "today" used
    in equality expression. That two "today"'s are not the same
    memory locations, even if they contain the same sequences
    of characters.

    > So, my question is how do we compare arrays and
    > char *


    strcpy() or strncpy() ;)

    > (I found that it is so commonly used as string)?


    No, it's commonly used to POINT AT character strings/arrays.

    > one more question: is it true that we have to initialize
    > a char * or points it to somewhere in memory


    Yes. Especially for automatic [local] objects, because they're
    not zero-initialized by default and contain garbage [for
    pointers: they're aimed at random memory locations].

    > or to malloc memory to it before we can use it?


    Yes, they should point to allocated memory - either by
    new/malloc(), or allocated by compiler itself [defined].

    > Because I got segfault several times arising from
    > this problem too.


    Read some about pointers and string literals.

    --
    SasQ
    SasQ, Mar 17, 2007
    #2
    1. Advertising

  3. william

    hijkl Guest

    hey
    you tring to compare constant stinf to char *. first of all you need
    to do type casting.
    example
    String s = "today"
    if ( str == (char *)s.c_str())

    but i think you cant use "==" with char *. you can use with c++ string
    variable.

    so u could do like this
    if ( strcmp(str,(char *)s.c_str()) == 0)

    correct me if i am wrong :)


    int main()
    {
    char *str=NULL;
    char x[]="today is good!";
    char *s="today";
    printf("%s", str);
    str=strtok(x," ");
    if (strcmp(str,s) == 0) //<==here is line that confuses me
    printf("they equals!\n");
    getch();
    return 0;
    }

    thanks
    sanjay

    On Mar 17, 1:23 pm, SasQ <> wrote:
    > Dnia Sat, 17 Mar 2007 12:01:03 -0700, william napisa³(a):
    >
    > > #include <stdio.h>

    >
    > In C++ it is #include <cstdio>
    >
    > > int main()
    > > {
    > > char *str=NULL;
    > > char x[]="today is good!";
    > > printf("%s", str);

    >
    > You're trying to print something pointed by a null pointer
    > [a pointer that points to "nowhere"]. Accessing a null pointer
    > in C++ is UB. It may crash, it my print "(null)", it may print
    > some garbage or do nothing.
    >
    > > str=strtok(x," ");

    >
    > Now you're setting the pointer to the first token found by
    > strtok. It doesn't point to nowhere until now. It points to
    > a beginning of "today\0is good!\0"... [the strtok put the
    > NUL character after first token "today"].
    >
    > > if (str=="today") //<==here is line that confuses me
    > > printf("they equals!\n");
    > > return 0;
    > > }

    >
    > > I printed "str" first, and the console displayed "today".

    >
    > For me it displays "(null)". And it's true, because the
    > 'str' pointer passed to the first printf is set to nowhere.
    >
    > > However, when I try to comapare 'str' with "today", the
    > > condition failed!

    >
    > And it's proper behaviour, because you're comparing the
    > pointers [not strings], and they point to different memory
    > locations ;) So they're not equal.
    >
    > > Exactly speaking, I know that 'str' is a 4 byte pointer

    >
    > On some platforms ;)
    >
    > > of char type, so it is not equal to a string.

    >
    > What string? Do you mean that literal constant?
    >
    > > But even in the gdb, I used 'p str', it printed "today".

    >
    > And it's also OK, because 'str' points to a memory location,
    > where "today" lays. But it's not the same "today" as the one
    > you compare with ;P The first "today" is the part of the
    > array x, and the second is the literal constant "today" used
    > in equality expression. That two "today"'s are not the same
    > memory locations, even if they contain the same sequences
    > of characters.
    >
    > > So, my question is how do we compare arrays and
    > > char *

    >
    > strcpy() or strncpy() ;)
    >
    > > (I found that it is so commonly used as string)?

    >
    > No, it's commonly used to POINT AT character strings/arrays.
    >
    > > one more question: is it true that we have to initialize
    > > a char * or points it to somewhere in memory

    >
    > Yes. Especially for automatic [local] objects, because they're
    > not zero-initialized by default and contain garbage [for
    > pointers: they're aimed at random memory locations].
    >
    > > or to malloc memory to it before we can use it?

    >
    > Yes, they should point to allocated memory - either by
    > new/malloc(), or allocated by compiler itself [defined].
    >
    > > Because I got segfault several times arising from
    > > this problem too.

    >
    > Read some about pointers and string literals.
    >
    > --
    > SasQ
    hijkl, Mar 17, 2007
    #3
  4. william

    Rolf Magnus Guest

    william wrote:

    > #include <stdio.h>
    >
    > int main()
    > {
    > char *str=NULL;
    > char x[]="today is good!";
    > printf("%s", str);
    > str=strtok(x," ");
    > if (str=="today") //<==here is line that confuses me
    > printf("they equals!\n");
    > return 0;
    > }
    >
    > I printed "str" first, and the console displayed "today".


    Your printf in the above program invokes undefined behavior, since it
    dereferences a null pointer.

    > However, when I try to comapare 'str' with "today", the condition failed!


    That's to be expected.

    > Exactly speaking, I know that 'str' is a 4 byte pointer of char type,


    The size of a pointer is implementation-defined. Let's simply stick
    with "pointer to char".

    > so it is not equal to a string.


    Before the comparison, the string literal gets converted into a pointer to
    const char.

    > But even in the gdb, I used 'p str', it printed "today".


    So? You have two pointers pointing to different memory locations. For the
    result of that comparison, the content of that memory location (or any of
    the following ones) doesn't matter.

    > So, my question is how do we compare arrays and char *(I found that it
    > is so commonly used as string)?


    It would be better to use std::vector and std::string instead of raw arrays,
    pointers and C style strings. Vectors and strings can be compared using ==.
    If you must use arrays and C style strings, use std::strcmp() from <cstring>
    to compare the strings. For arrays, use std::equal from <algorithm>.

    > one more question: is it true that we have to initialize a char * or
    > points it to somewhere in memory, or to malloc memory to it before we
    > can use it?


    Yes.

    > Because I got segfault several times arising from this problem too.


    Well, if you use it to read from the address it points to without actually
    letting it point to anything, that's not surprising.
    Rolf Magnus, Mar 17, 2007
    #4
  5. william

    SasQ Guest

    Dnia Sat, 17 Mar 2007 21:23:04 +0100, SasQ napisa³(a):

    Sorry, a little errata:

    > Now you're setting the pointer to the first token found by
    > strtok. It doesn't point to nowhere until now.


    Should be "from now on" instead of "until now".
    [English isn't my native language ;P]

    >> So, my question is how do we compare arrays and char *

    >
    > strcpy() or strncpy() ;)


    Should be "strcmp() or strncmp()"

    --
    SasQ
    SasQ, Mar 17, 2007
    #5
  6. william

    Rolf Magnus Guest

    SasQ wrote:

    > Dnia Sat, 17 Mar 2007 21:23:04 +0100, SasQ napisał(a):
    >
    > Sorry, a little errata:
    >
    >> Now you're setting the pointer to the first token found by
    >> strtok. It doesn't point to nowhere until now.

    >
    > Should be "from now on" instead of "until now".
    > [English isn't my native language ;P]


    Depends on how the double negation is to be interpreted. ;-)
    Rolf Magnus, Mar 17, 2007
    #6
  7. william

    SasQ Guest

    Dnia Sat, 17 Mar 2007 13:28:25 -0700, hijkl napisa³(a):

    > you tring to compare constant stinf to char *.


    Rather a string literal constant value
    ["string literal" in short].

    > first of all you need to do type casting.


    It's not the case here.

    > example:
    > String s = "today"


    Somebody was hungry and has eaten the semicolon :p

    > if ( str == (char *)s.c_str())


    ZOMG o_O
    Mixing high-level C++ object code with low-level C-like
    code is like mixing a chocolate with a shit :p
    And it still won't work, because you're still comparing
    two pointers and the equality will be true only if they're
    both pointing to the same memory location. If they point
    to the different memory locations, the result will be false,
    even if they point to the same sequences of characters.
    Neither std::string nor casting won't help here :p

    > but i think you cant use "==" with char *.


    He can, but the effects will be different from that he
    [and you] suppose ;P

    > you can use with c++ string variable.


    That's the only true sentence you said in this post ;)

    > so u could do like this
    > if ( strcmp(str,(char *)s.c_str()) == 0)


    OMFG @_@
    Why not use just the std::string in all cases?

    std::string str1 = "string"; //literal 1 goes to str1
    std::string str2 = "string"; //literal 2 goes to str2
    if (str1==str2) std::cout << "They're equal";

    But remember that equal values not means the same objects.
    Look at this carefully:

    int x = 2;
    int y = 2; //another two, not the same as previous
    if (x==y) std::cout << "x and y contains the same values";
    if (&x==&y) std::cout << "x and y are the same objects";
    else std::cout << "x and y are not the same objects";

    BUT... :p
    If the use of strtok() is necessary, it might be impossible
    to use std::string everywhere, i.e. strtok() returns pointer
    to character string, and it's reasonable to use that pointer
    for efficiency. Then you must not to compare the string
    pointed by that pointer with a string pointed by a pointer
    returned from std::string::c_str(). You can simply use
    strcmp() with a 'str' pointer and literal constant as a
    parameters, like that:

    str = strtok(x," ");
    if ( strcmp(str,"some string literal") ) {
    //they're pointing to strings equal by value
    }

    > correct me if i am wrong :)


    So you got what you asked for ;)


    PS: Cut citations in your posts.

    --
    SasQ
    SasQ, Mar 17, 2007
    #7
  8. william

    Default User Guest

    william wrote:


    > I printed "str" first, and the console displayed "today". However,
    > when I try to comapare 'str' with "today", the condition failed!


    Don't multi-post. You posted the question on comp.lang.c (where it was
    thoroughly answered).




    Brian
    Default User, Mar 17, 2007
    #8
  9. william

    william Guest

    On Mar 17, 4:23 pm, SasQ <> wrote:
    > Dnia Sat, 17 Mar 2007 12:01:03 -0700, william napisa³(a):
    >
    > > #include <stdio.h>

    >
    > In C++ it is #include <cstdio>
    >
    > > int main()
    > > {
    > > char *str=NULL;
    > > char x[]="today is good!";
    > > printf("%s", str);

    >
    > You're trying to print something pointed by a null pointer
    > [a pointer that points to "nowhere"]. Accessing a null pointer
    > in C++ is UB. It may crash, it my print "(null)", it may print
    > some garbage or do nothing.
    >
    > > str=strtok(x," ");

    >
    > Now you're setting the pointer to the first token found by
    > strtok. It doesn't point to nowhere until now. It points to
    > a beginning of "today\0is good!\0"... [the strtok put the
    > NUL character after first token "today"].
    >
    > > if (str=="today") //<==here is line that confuses me
    > > printf("they equals!\n");
    > > return 0;
    > > }

    >
    > > I printed "str" first, and the console displayed "today".

    >
    > For me it displays "(null)". And it's true, because the
    > 'str' pointer passed to the first printf is set to nowhere.
    >
    > > However, when I try to comapare 'str' with "today", the
    > > condition failed!

    >
    > And it's proper behaviour, because you're comparing the
    > pointers [not strings], and they point to different memory
    > locations ;) So they're not equal.
    >
    > > Exactly speaking, I know that 'str' is a 4 byte pointer

    >
    > On some platforms ;)
    >
    > > of char type, so it is not equal to a string.

    >
    > What string? Do you mean that literal constant?
    >
    > > But even in the gdb, I used 'p str', it printed "today".

    >
    > And it's also OK, because 'str' points to a memory location,
    > where "today" lays. But it's not the same "today" as the one
    > you compare with ;P The first "today" is the part of the
    > array x, and the second is the literal constant "today" used
    > in equality expression. That two "today"'s are not the same
    > memory locations, even if they contain the same sequences
    > of characters.
    >
    > > So, my question is how do we compare arrays and
    > > char *

    >
    > strcpy() or strncpy() ;)
    >
    > > (I found that it is so commonly used as string)?

    >
    > No, it's commonly used to POINT AT character strings/arrays.
    >
    > > one more question: is it true that we have to initialize
    > > a char * or points it to somewhere in memory

    >
    > Yes. Especially for automatic [local] objects, because they're
    > not zero-initialized by default and contain garbage [for
    > pointers: they're aimed at random memory locations].
    >
    > > or to malloc memory to it before we can use it?

    >
    > Yes, they should point to allocated memory - either by
    > new/malloc(), or allocated by compiler itself [defined].
    >
    > > Because I got segfault several times arising from
    > > this problem too.

    >
    > Read some about pointers and string literals.
    >
    > --
    > SasQ


    Thank you very much, SasQ
    william, Mar 19, 2007
    #9
  10. william

    william Guest


    > str = strtok(x," ");
    > if ( strcmp(str,"some string literal") ) {
    > //they're pointing to strings equal by value
    > }
    >


    Yes, this worked totally well.
    > > correct me if i am wrong :)

    >
    > So you got what you asked for ;)
    >
    > PS: Cut citations in your posts.
    >
    > --
    > SasQ
    william, Mar 19, 2007
    #10
  11. william

    Gavin Deane Guest

    On 17 Mar, 20:23, SasQ <> wrote:
    > Dnia Sat, 17 Mar 2007 12:01:03 -0700, william napisa³(a):
    >
    > > #include <stdio.h>

    >
    > In C++ it is #include <cstdio>


    You only made half the correction. If you change <stdio.h> to <cstdio>
    then you need to change printf to std::printf. And unless you're going
    to be inconsistent, you'll want to include <cstring> rather than
    <string.h> so strcmp and friends will also be in the std namespace.

    Or you could decide that since most compilers implement <cxxx> headers
    incorrectly, putting names in both the std and the global namespace
    (so use of printf rather than std::printf often works after including
    <cstdio>), then the choice _in practice_ is between technically
    deprecated code compiling successfully and technically incorrect code
    compiling successfully, in which case the <cxxx> headers aren't worth
    bothering with. That's my approach. YMMV.

    Gavin Deane
    Gavin Deane, Mar 19, 2007
    #11
    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. Zach
    Replies:
    3
    Views:
    5,518
    Mike Wahler
    Dec 12, 2004
  2. , India

    Comparing char * with string literal

    , India, Mar 8, 2007, in forum: C Programming
    Replies:
    9
    Views:
    496
    Malcolm McLean
    Mar 8, 2007
  3. william
    Replies:
    18
    Views:
    532
    CBFalconer
    Mar 19, 2007
  4. kaoruAngel

    Set literal confusion

    kaoruAngel, Sep 22, 2009, in forum: Python
    Replies:
    5
    Views:
    351
    Dennis Lee Bieber
    Sep 23, 2009
  5. Anonieko Ramos

    What's wrong with rpc-literal? Why use doc-literal?

    Anonieko Ramos, Sep 27, 2004, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    356
    Anonieko Ramos
    Sep 27, 2004
Loading...

Share This Page