Thread: Strtok() usage question/Search for a token without modification...

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    84

    Strtok() usage question/Search for a token without modification...

    I am trying to be able to search a string for a token/word without modifying the original string... So I can then perform multiple searches on a single string for a variety of tokens/keywords, testing then to see if it returns NULL (i.e. then the token is not present).

    Is this possible?

    My code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
      
      char                s1[] = "BCFG -SHRA BR"; // "this is an,example  ; "
      char                s2[] = "FG";
      char                s3[] = "X";
      char                *p;
      char                a[11], b[11], c[11];
      int                 n_char;
    /* strtok example/test */
    /* Caveat: strtok modifies the incoming string! */
      printf("The original string is: %s\n", s1);
      n_char = strlen(s1) + 1;
    
    /* Add s1 to the end of s3 */
      strncat(s3, s1, n_char);
      printf("The new larger string is: %s\n", s3);
      
      p = strtok(s3,s2);
    //  printf("%s\n", strtok(s1, s2));
      printf("%s\n", p);
      p = strtok(s3, s2);
      printf("%s\n", p);
      p = strtok(s3, "-");
      printf("%s\n", p);
      p = strtok(s3, "BC");
      printf("%s\n", p);
      p = strtok(s3, "Panda");
      if(p == NULL)
        printf("Token not found\n");
      p = strtok(s3, "BC");
      printf("%s\n", p);
      putchar("\n");
    
      return 0;
    }
    It is not compiling at the moment...

    So it should print:
    "XBC"
    "XBC"
    "XBCFG"
    "X"
    "Token not found"
    "X"

    Put, it does not and when compling I get:
    ld: in strtok_example, can't link with a main executable
    collect2: ld returned 1 exit status

    and output:
    The original string is: BCFG -SHRA BR
    The new larger string is: XBCFG -SHRA BR
    X
    X
    X
    X


    Thoughts?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Use strtok() on a copy of the original string.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Feb 2010
    Posts
    84
    Thats what I originally thought, but if I have say 20 odd tokens I am searching for, I was hoping there would be a more efficient way than making 20 odd copies of the original and checking each one....

    :-/

  4. #4
    Registered User
    Join Date
    Feb 2010
    Posts
    84
    Update:

    Now, copying and mallocing memory accordingly...

    Code:
    int main(void)
    {
      char                s1[] = "BCFG -SHRA BR"; // "this is an,example  ; "
      char                s2[] = "FG";
      char                s3[] = "X";
      char                *p1, *p2, *p3, *p4, *p5, *p6;
      char                a[11], b[11], c[11];
      int                 n_char;
    /* strtok example/test */
    /* Caveat: strtok modifies the incoming string! */
      printf("The original string is: %s\n", s1);
      n_char = strlen(s1) + 1;
    
    /* Add s1 to the end of s3 */
      strncat(s3, s1, n_char);
      printf("The new larger string is: %s\n", s3);
    
      p1 = malloc( (sizeof(s3) + 1) * sizeof(char));
      p2 = malloc( (sizeof(s3) + 1) * sizeof(char));
      p3 = malloc( (sizeof(s3) + 1) * sizeof(char));
      p4 = malloc( (sizeof(s3) + 1) * sizeof(char));
      p5 = malloc( (sizeof(s3) + 1) * sizeof(char));
      p6 = malloc( (sizeof(s3) + 1) * sizeof(char));
      strcpy(p1,s3);
      strcpy(p2,s3);
      strcpy(p3,s3);
      strcpy(p4,s3);
      strcpy(p5,s3);
      strcpy(p6,s3);
    
      p1 = strtok(p1,s2);
    //  printf("%s\n", strtok(s1, s2));
      printf("%s\n", p1);
      
      p2 = strtok(p2, s2);
      printf("%s\n", p2);
      
      p3 = strtok(p3, "-");
      printf("%s\n", p3);
    
      p4 = strtok(p4, "BC");
      printf("%s\n", p4);
    
      p5 = strtok(p5, "Panda");
      if(p5 == NULL){
        printf("Token not found \n");
      }
    
      p6 = strtok(p6, "BC");
      printf("%s\n", p6);
    
      return 0;
    }
    Output is:

    The original string is: BCFG -SHRA BR
    The new larger string is: XBCFG -SHRA BR
    X
    X
    XBCFG
    X
    X

    Not what I expected at all! I expect
    XBC
    XBC
    XBCFG
    X
    Token not found
    x

    Err Hmm

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Code:
    strncat(s3, s1, n_char);
    You can't do this. s3 is only two bytes long, so there's no space into which you can append.

  6. #6
    Registered User
    Join Date
    Feb 2010
    Posts
    84
    Well I tried making this adjustment:
    Code:
      char *s3;
      s3 = malloc( ((n_char) + 2) * sizeof(char));
      strcpy(s3, "X");
    then add s1 to s3... But i get the same result (unexpected output)

    It looks like:
    The original string is: BCFG -SHRA BR
    s3 = X
    The new larger string is: XBCFG -SHRA BR
    XBC
    XBC
    XBCFG
    X
    X


    It should return a NULL and print out my print statement of not finding the token, when it looks for "PANDA"....
    Last edited by towed; 06-17-2010 at 10:54 AM.

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    If you just want to know if a string contains a sub-string, and don't want to change anything, why not use strstr(), or strchr(), instead?

    It can search for one target string/char, or for every target string/char, in the line of the char array. Neither will make any changes or require any duplicate strings be made.

  8. #8
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    It should return a NULL and print out my print statement of not finding the token, when it looks for "PANDA"....
    This is not how strtok() works. Quoting C99: "char *strtok(char * restrict s1, const char * restrict s2); ... The first call in the sequence [of calls to strtok()] searches the string pointed to by s1 for the first character that is not contained in the current separator string pointed to by s2."

    There's more, obviously, but the point is that a token starts at the first non-delimiter character, and extends to the first delimiter; or if there is no delimiter at all, the entire string is a token.

    It seems, also, that your expectation of how the second argument to strtok() works is incorrect (but this is merely an inference on my part). It is not treated as a string that serves as a delimiter. Rather, it is a collection of characters, each of which servers as a delimiter. So strtok(p4, "BC) treats both 'B' and 'C' as delimiters, not the string "BC" as one. It will obviously tokenize fine when it finds a BC, but it will act the same if it finds either a B or a C standing alone,

  9. #9
    Registered User
    Join Date
    Feb 2010
    Posts
    84
    I will investigate strstr().

    Cas: I was incorrect, I though if the token was "PANDA" it would treat the whole thing as a delimiter.

  10. #10
    Registered User
    Join Date
    Feb 2010
    Posts
    84
    IT appears it better suited for what I am trying to do:

    Code:
    int main(void)
    {
    
      char *largestring = "BCFG -SHRA BR";
      char *string1 = "FG";
      char *string2 = "BR";
      char *string3 = "PANDA";
      char *string4 = "-";
      char *ptr;
    
      ptr = strstr(largestring, string1);
      if(ptr != NULL){
        printf("%s was found in %s\n", string1, largestring);
      } else
        printf("%s was not found\n", string1);
      printf("The address is %p\n", ptr);
    
      ptr = strstr(largestring, string2);
      if(ptr != NULL){
        printf("%s was found in %s\n", string2, largestring);
      } else
        printf("%s was not found\n", string2);
      printf("The address is %p\n", ptr);
    
    
      ptr = strstr(largestring, string3);
      if(ptr != NULL){
        printf("%s was found in %s\n", string3, largestring);
      } else
        printf("%s was not found\n", string3);
      printf("The address is %p\n", ptr);
    
    
      ptr = strstr(largestring, string4);
      if(ptr != NULL){
        printf("%s was found in %s\n", string4, largestring);
      } else
        printf("%s was not found\n", string4);
      printf("The address is %p\n", ptr);
    
      return 0;
    }
    Does do the correct behavior...

    Output:
    FG was found in BCFG -SHRA BR
    The address is 0x1fad
    BR was found in BCFG -SHRA BR
    The address is 0x1fb6
    PANDA was not found
    The address is 0x0
    - was found in BCFG -SHRA BR
    The address is 0x1fb0


    THOUGH. Is it "legal" to be reassigning ptr like I do? Since the base address of the substring is returned if found or else null is returning. I am just assigning the address or NULL over again and replacing the previous one...
    Last edited by towed; 06-17-2010 at 12:05 PM.

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Sure. Pointers are just like any other variable, they hold a value. They can hold whatever value you want (that fits in the data type). As long as you're pointing at something valid, point away.


    Quzah.
    Hope is the first step on the road to disappointment.

  12. #12
    Registered User
    Join Date
    Jun 2010
    Posts
    7
    Your usage of strtok() is incorrect. I suggest that you take a look at the man page for the function. Here's a hint: the first parameter of strtok is not the character pointer for subsequent calls to the function.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Connecting to a mysql server and querying problem
    By Diod in forum C++ Programming
    Replies: 8
    Last Post: 02-13-2006, 10:33 AM
  2. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  3. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  4. Resource ICONs
    By gbaker in forum Windows Programming
    Replies: 4
    Last Post: 12-15-2003, 07:18 AM
  5. Parsing and Tokens (strtok)
    By readerwhiz in forum C Programming
    Replies: 6
    Last Post: 04-22-2002, 09:57 AM