'Implementation of strtok()

I can't find an error in the implementation of strtok().

After executing the program, I get:

test1
test2

Instead of:

test1 
test2 
test3 
test4 
test5 
test6

This is my program:

#include <stdio.h>

char* sffut(char* s, char* c) {
    char* s1;
    char* c1;
    for (s1 = s; *s1 != '\0'; ++s1)
        for (c1 = c; *c1 != '\0'; ++c1) {

            if (*s1 == *c)
                return (char*)s1;
        }

    return 0;
}

char* stok(char* s, char* delim) {
    char* firsttok = s;
    char* endtok;
    if (firsttok == NULL)
        return NULL;
    endtok = sffut(firsttok, delim);
    if (endtok)
        *endtok++ = '\0';
    s = endtok;
    return firsttok;
}

int main(void) {
    char str[] = "test1, test2. test3/ test4 - test5: test6";

    char* tok = stok(str, ".,/:;- ");

    while (tok) {
        printf("%s\n", tok);
        tok = stok(NULL, ".,/:;- ");
    }
}


Solution 1:[1]

The implementation is entirely wrong. For each call like below where the first argument is NULL

tok = stok(NULL, ".,/:;- ");

the function stok at once returns NULL

  char* stok(char* s, char* delim)
  {
      char* firsttok = s;
      char* endtok;
      if (firsttok == NULL)
          return NULL;
      //...  
  }

Also in the function sffut within the inner for loop there is compared a character from the string s always with the first character of the string c.

  char* sffut(char* s, char* c)
  {
      char* s1;
      char* c1;
      for (s1 = s; *s1 != '\0'; ++s1)
          for (c1 = c; *c1 != '\0'; ++c1) {

              if (*s1 == *c)  // <===
                  return (char*)s1;
          }

      return 0;
  }

It seems you mean at least

if (*s1 == *c1)

To implement the function strtok you need within your function to declare a static variable of the type char * that will store the current substring and be used between calls of the function.

A straightforward approach to implement the function is by using standard C string functions strspn and strcspn or by writing such functions yourself.

Here is a demonstration program.

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

char *stok( char *s1, const char *s2 )
{
    static char *p;

    if (s1 != NULL) p = s1;

    if (p == NULL) return NULL;

    p += strspn( p, s2 );

    if (*p == '\0')
    {
        p = NULL;
        return p;
    }
    else
    {
        char *start = p;
        p += strcspn( p, s2 );
        if (*p == '\0')
        {
            p = NULL;
        }
        else
        {
            *p++ = '\0';
        }

        return start;
    }
}

int main( void )
{
    char s1[] = "test1, test2. test3/ test4 - test5: test6";
    const char *s2 = ".,/:;- ";

    char *tok = stok( s1, s2 );

    while (tok != NULL)
    {
        puts( tok );
        tok = stok( NULL, s2 );
    }
}

The program output is

test1
test2
test3
test4
test5
test6

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1