In this line:
while ((*tkn != 0) && (tkn != NULL))
you need to reverse the conditions. If tkn
is a null pointer, you will crash when the first term is evaluated. If you need to check a pointer for validity, do so before dereferencing it.
while (tkn != NULL && *tkn != '\0')
The extra parentheses you added do no harm but are not necessary. And although 0
is a perfectly good zero, the '\0'
emphasizes that *tkn
is a character. Of course, given the prior tkn != NULL
condition in the if statement, there is no real need to repeat the check in the while loop.
Working code based on yours - some work left to do for subsequent tokens in the string, for example...
#include <stdlib.h>
#include <string.h>
enum { MAX = 20 };
char *tkn;
char array[MAX];
char str[2*MAX];
void tokenize(void)
{
int i = 0;
array[0] = '\0';
tkn = strtok(str, " "); // get token 1
if (tkn != NULL)
{
printf("token1: ");
while (tkn != NULL && *tkn != '\0' && i < MAX - 1)
{
putchar(*tkn);
array[i++] = *tkn++;
}
*tkn = '\0';
putchar('\n');
}
}
int main(void)
{
strcpy(str, "abc def");
tokenize();
printf("token = <<%s>>\n", array);
strcpy(str, "abcdefghijklmnopqrstuvwxyz");
tokenize();
printf("token = <<%s>>\n", array);
return(0);
}
Sample output:
token1: abc
token = <<abc>>
token1: abcdefghijklmnopqrs
token = <<abcdefghijklmnopqrs>>
Asked:
But what if I am taking in a string 'abc 3fc ghi' and I want to use just '3fc' in another function that say converts it from ascii to hex? How do I just use say tkn2 for 3fc and get that only using a pointer? – patrick 9 mins ago
That's where it gets trickier because strtok()
has a moderately fiendish interface.
Leaving tokenize()
unchanged, let's redefine str
:
char *str;
Then, we can use (untested):
int main(void)
{
char buffer[2*MAX];
strcpy(buffer, "abc 3fc ghi");
str = buffer;
tokenize();
printf("token = <<%s>>\n", array); // "abc"
str = NULL;
tokenize();
printf("token = <<%s>>\n", array); // "3fc"
str = NULL;
tokenize();
printf("token = <<%s>>\n", array); // "ghi"
return(0);
}
Clearly, this relies on knowing that there are three tokens. To generalize, you'd need the tokenizer to tell you when there's nothing left to tokenize.
Note that having tkn
as a global is really unnecessary - indeed, you should aim to avoid globals as much as possible.