Why occur the mistake in runtime about strtok()?

Discussion in 'C Programming' started by hu, Jun 18, 2006.

  1. hu

    hu Guest

    hi, everybody!
    I'm testing the fuction of strtok(). The environment is WinXP, VC++6.0.
    Program is simple, but mistake is confusing. First, the below code can get
    right outcome:"ello world, hello dreams."

    #include <stdafx.h>
    #include <string.h>
    #include <stdio.h>

    int main()
    {
    char *pStr = "Hello world, hello dreams.";
    char *p = pStr;
    p = strtok(pStr, "H");
    if (NULL==p)
    printf("null__");
    else
    printf("%s", p);

    return (0);
    }

    Second, Changing the sentence:
    p = strtok(pStr, "H");
    to
    p = strtok(pStr, "Ho");
    It can be compiled, but cannot run!

    Third, Changing the sentence:
    p = strtok(pStr, "H");
    to
    p = strtok(pStr, "e");
    It can be compiled, but cannot run too!

    Where is the wrong?
    thanks!
     
    hu, Jun 18, 2006
    #1
    1. Advertising

  2. hu

    Ian Collins Guest

    hu wrote:
    > hi, everybody!
    > I'm testing the fuction of strtok(). The environment is WinXP, VC++6.0.
    > Program is simple, but mistake is confusing. First, the below code can get
    > right outcome:"ello world, hello dreams."
    >
    > #include <stdafx.h>
    > #include <string.h>
    > #include <stdio.h>
    >
    > int main()
    > {
    > char *pStr = "Hello world, hello dreams.";
    > char *p = pStr;
    > p = strtok(pStr, "H");


    This invokes undefined behaviour, you are calling strtok with a string
    literal. strtok overwrites the string you pass it, doing this with a
    literal is undefined.

    --
    Ian Collins.
     
    Ian Collins, Jun 18, 2006
    #2
    1. Advertising

  3. "hu" <> writes:
    > I'm testing the fuction of strtok(). The environment is WinXP, VC++6.0.
    > Program is simple, but mistake is confusing. First, the below code can get
    > right outcome:"ello world, hello dreams."
    >
    > #include <stdafx.h>
    > #include <string.h>
    > #include <stdio.h>
    >
    > int main()
    > {
    > char *pStr = "Hello world, hello dreams.";
    > char *p = pStr;
    > p = strtok(pStr, "H");
    > if (NULL==p)
    > printf("null__");
    > else
    > printf("%s", p);
    >
    > return (0);
    > }
    >
    > Second, Changing the sentence:
    > p = strtok(pStr, "H");
    > to
    > p = strtok(pStr, "Ho");
    > It can be compiled, but cannot run!
    >
    > Third, Changing the sentence:
    > p = strtok(pStr, "H");
    > to
    > p = strtok(pStr, "e");
    > It can be compiled, but cannot run too!
    >
    > Where is the wrong?


    Three things. First, you're using a non-standard header <stdafx.h>.
    Second, you're trying to modify a string literal (that's your real
    problem). Third, you're you're not telling us how it fails; "cannot
    run" wouldn't have given us much information if the actual problem
    didn't happen to be obvious.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Jun 18, 2006
    #3
  4. hu

    hu Guest

    the strtok() declaration:
    char * strtok(char *p1, const char*p2);
    The strtok() can overwrite *p1? And what it overwirte the content of p1
    with?

    thanks!

    "Ian Collins" <>
    ??????:...
    > hu wrote:
    >> hi, everybody!
    >> I'm testing the fuction of strtok(). The environment is WinXP,
    >> VC++6.0.
    >> Program is simple, but mistake is confusing. First, the below code can
    >> get
    >> right outcome:"ello world, hello dreams."
    >>
    >> #include <stdafx.h>
    >> #include <string.h>
    >> #include <stdio.h>
    >>
    >> int main()
    >> {
    >> char *pStr = "Hello world, hello dreams.";
    >> char *p = pStr;
    >> p = strtok(pStr, "H");

    >
    > This invokes undefined behaviour, you are calling strtok with a string
    > literal. strtok overwrites the string you pass it, doing this with a
    > literal is undefined.
    >
    > --
    > Ian Collins.
     
    hu, Jun 19, 2006
    #4
  5. hu

    pete Guest

    hu wrote:
    >
    > the strtok() declaration:
    > char * strtok(char *p1, const char*p2);
    > The strtok() can overwrite *p1?
    > And what it overwirte the content of p1 with?


    You seem to have no idea of what strtok does.

    N869
    7.21.5.8 The strtok function
    Synopsis
    [#1]
    #include <string.h>
    char *strtok(char * restrict s1,
    const char * restrict s2);
    Description
    [#2] A sequence of calls to the strtok function breaks the
    string pointed to by s1 into a sequence of tokens, each of
    which is delimited by a character from the string pointed to
    by s2. The first call in the sequence has a non-null first
    argument; subsequent calls in the sequence have a null first
    argument. The separator string pointed to by s2 may be
    different from call to call.
    [#3] The first call in the sequence searches the string
    pointed to by s1 for the first character that is not
    contained in the current separator string pointed to by s2.
    If no such character is found, then there are no tokens in
    the string pointed to by s1 and the strtok function returns
    a null pointer. If such a character is found, it is the
    start of the first token.
    [#4] The strtok function then searches from there for a
    character that is contained in the current separator string.
    If no such character is found, the current token extends to
    the end of the string pointed to by s1, and subsequent
    searches for a token will return a null pointer. If such a
    character is found, it is overwritten by a null character,
    which terminates the current token. The strtok function
    saves a pointer to the following character, from which the
    next search for a token will start.
    [#5] Each subsequent call, with a null pointer as the value
    of the first argument, starts searching from the saved
    pointer and behaves as described above.
    [#6] The implementation shall behave as if no library
    function calls the strtok function.
    Returns
    [#7] The strtok function returns a pointer to the first
    character of a token, or a null pointer if there is no
    token.
    [#8] EXAMPLE 1
    #include <string.h>
    static char str[] = "?a???b,,,#c";
    char *t;
    t = strtok(str, "?"); // t points to the token "a"
    t = strtok(NULL, ","); // t points to the token "??b"
    t = strtok(NULL, "#,"); // t points to the token "c"
    t = strtok(NULL, "?"); // t is a null pointer


    --
    pete
     
    pete, Jun 19, 2006
    #5
  6. hu

    hu Guest

    I said "can not run", I mean that when I start the program, WindowsXP pop a
    illegal operation dialog box.

    thanks a lot.


    "Keith Thompson" <> ??????:...
    > "hu" <> writes:
    >> I'm testing the fuction of strtok(). The environment is WinXP,
    >> VC++6.0.
    >> Program is simple, but mistake is confusing. First, the below code can
    >> get
    >> right outcome:"ello world, hello dreams."
    >>
    >> #include <stdafx.h>
    >> #include <string.h>
    >> #include <stdio.h>
    >>
    >> int main()
    >> {
    >> char *pStr = "Hello world, hello dreams.";
    >> char *p = pStr;
    >> p = strtok(pStr, "H");
    >> if (NULL==p)
    >> printf("null__");
    >> else
    >> printf("%s", p);
    >>
    >> return (0);
    >> }
    >>
    >> Second, Changing the sentence:
    >> p = strtok(pStr, "H");
    >> to
    >> p = strtok(pStr, "Ho");
    >> It can be compiled, but cannot run!
    >>
    >> Third, Changing the sentence:
    >> p = strtok(pStr, "H");
    >> to
    >> p = strtok(pStr, "e");
    >> It can be compiled, but cannot run too!
    >>
    >> Where is the wrong?

    >
    > Three things. First, you're using a non-standard header <stdafx.h>.
    > Second, you're trying to modify a string literal (that's your real
    > problem). Third, you're you're not telling us how it fails; "cannot
    > run" wouldn't have given us much information if the actual problem
    > didn't happen to be obvious.
    >
    > --
    > Keith Thompson (The_Other_Keith)
    > <http://www.ghoti.net/~kst>
    > San Diego Supercomputer Center <*>
    > <http://users.sdsc.edu/~kst>
    > We must do something. This is something. Therefore, we must do this.
     
    hu, Jun 19, 2006
    #6
  7. hu

    Chris Dollin Guest

    hu wrote:

    > I said "can not run", I mean that when I start the program, WindowsXP pop a
    > illegal operation dialog box.


    (a) Please don't top-post.

    (b) So, by "can not run", you mean "did run, and broke", or just "crashed".

    --
    Chris "don't attempt to modify string literals" Dollin
    "Reaching out for mirrors hidden in the web." - Renaissance, /Running Hard/
     
    Chris Dollin, Jun 19, 2006
    #7
  8. hu

    CBFalconer Guest

    hu wrote:
    >
    > I said "can not run", I mean that when I start the program,
    > WindowsXP pop a illegal operation dialog box.


    Please do not top-post, especially in technical newsgroups. Your
    answer belongs after (or possibly intermixed with) the quoted (and
    snipped) material to which you reply.

    See the following links for further information

    --
    Some informative links:
    news:news.announce.newusers
    http://www.geocities.com/nnqweb/
    http://www.catb.org/~esr/faqs/smart-questions.html
    http://www.caliburn.nl/topposting.html
    http://www.netmeister.org/news/learn2quote.html
     
    CBFalconer, Jun 19, 2006
    #8
  9. hu

    John Bode Guest

    hu wrote:
    > hi, everybody!
    > I'm testing the fuction of strtok(). The environment is WinXP, VC++6.0.
    > Program is simple, but mistake is confusing. First, the below code can get
    > right outcome:"ello world, hello dreams."
    >
    > #include <stdafx.h>
    > #include <string.h>
    > #include <stdio.h>
    >
    > int main()
    > {
    > char *pStr = "Hello world, hello dreams.";


    This is your problem. The strtok() function has to be able to modify
    the string being tokenized; it will overwrite each delimiter it finds
    with the nul character. Unfortunately, string literals may not be
    writable, so attempting to write to a string literal may invoke
    undefined behavior. The results of invoking undefined behavior may
    include running as expected, crashing outright, or something more
    subtle and difficult to debug.

    The easiest way to fix the problem is to change the above declaration
    to

    char pStr[] = "Hello world, hello dreams.";

    Instead of creating a pointer to a non-writable string literal, you've
    created an array that can be written to, and the array contents are
    initialized with a copy of the string literal.

    Grab your handy C reference manual and read up on string literals,
    arrays, and strtok().

    [snip remainder]
     
    John Bode, Jun 19, 2006
    #9
    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. Miguel Dias Moura
    Replies:
    4
    Views:
    484
    Hans Kesting
    May 6, 2004
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,261
    Smokey Grindel
    Dec 2, 2006
  3. Baby Lion

    Runtime error occur in vc

    Baby Lion, Mar 29, 2007, in forum: C++
    Replies:
    3
    Views:
    514
    David Harmon
    Mar 29, 2007
  4. Chris
    Replies:
    5
    Views:
    502
    timmy123 via DotNetMonster.com
    Jul 16, 2007
  5. Benjamin Kaplan

    Re: why did the WindowsError occur?

    Benjamin Kaplan, Sep 5, 2012, in forum: Python
    Replies:
    0
    Views:
    185
    Benjamin Kaplan
    Sep 5, 2012
Loading...

Share This Page