Okay, I have a problem. In this code, after the first call to strtok, the variable becomes "developer" when it was originally "developer;developer 0;developer". I would have expected it to become "developer 0;developer" after the first call..

void Con_Execute(char *text)
{
    char *pch;
    char string[10240];

    strcpy(string,text);

    if(!strstr(string,";"))
    {
        Cmd_ExecuteString(string);
        return;
    }

    pch = strtok(string,";");
    while(pch)
    {
        Cmd_ExecuteString(string);
        pch = strtok(NULL,";");
    }
}

Dani AI

Generated

Short answer: strtok replaces each delimiter with a NUL byte and returns a pointer to the current token. In your loop you call Cmd_ExecuteString(string) (the whole buffer) instead of Cmd_ExecuteString(pch) (the token). Change the call to use the token pointer:

pch = strtok(string, ";");
while (pch) {
    Cmd_ExecuteString(pch);
    pch = strtok(NULL, ";");
}

That is why you only ever see "developer" printed — after the first strtok the semicolon becomes '\0', so the buffer string now starts with the first token and printing it shows only that token. 's test demonstrates the same effect: the original buffer contains embedded NULs after tokenization. See the strtok docs for the exact behavior and lifetime of returned pointers: strtok documentation.

Notes and cautions:

  • Do not pass string literals to strtok; always give a modifiable buffer (you already copy into string, but avoid strcpy on un-checked sizes — use bounded copy/snprintf or check lengths first).
  • strtok is not reentrant. In threaded or nested parsing use strtok_r (POSIX) or strtok_s (Windows). For alternate semantics (returning the remainder pointer) consider strsep where available. See strtok_r docs for safer usage: strtok_r documentation.

Debug tip: if behavior still surprises, dump the buffer bytes (hexdump or print byte values) after the first strtok to see the inserted NULs.

Recommended Answers

All 2 Replies

Now I think I see what you're question is:

Try running this:

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

int main() {
  int i, unique; 
  char str[]="developer,developer0,developer";
  char *pstr;
  printf("\n\n original string: %s \n", str);
  pstr = strtok(str, ",");
  printf("\n  pointer: %s \n", pstr);
  printf("\n string[]: %s \n", str);


  while(1) {
    pstr = strtok(NULL, ",");
    if(!pstr)
      break;
    printf("\n  pointer: %s \n", pstr);
    printf("\n string[]: %s \n", str);
  }
  printf("\nFinal string prints as: %s \n", str);
  printf("\nBut the final string has visible char's of: \n");
  for(i=0;i<sizeof(str);i++)
    putchar(str[i]);
  
  printf("\n\n\t\t\t     press enter when ready");

  i = getchar(); ++i;
  return 0;
}

I don't understand, that's exactly what I did, but I only ever get the first 'developer' :(

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.