Operating System - Linux
1821981 Members
3175 Online
109638 Solutions
New Discussion юеВ

strtok_r return value..............

 
SOLVED
Go to solution
Tnameh
Occasional Advisor

strtok_r return value..............

Hello
I have string abc:def::::lkm. I am using strtok_r to find the substring and storing the value returned by it.

but strtok_r is not returning any value if their is nothing between delimiter.
#include
#include


int main()
{


char buffer[80], temp[80];
char *sep = ":";
char *brkt;

char *brkb;

char *word;

char *phrase;


strcpy(buffer, "This::abc:");

word = strtok_r(buffer, sep, &brkt);

printf("word : %s\n",word);
printf("brkt : %s\n",brkt);


word = strtok_r(NULL, sep, &brkt);

printf("word : %s\n",word);
printf("brkt : %s\n",brkt);

return 0;

}


Output is
$ ./abc
word : This
brkt : :abc:
word : abc
brkt :

Well I need is that it should return me Null if their is no string between two delimiter.Is their is any better way to handle it.

Hope i am clear.

9 REPLIES 9
A. Clay Stephenson
Acclaimed Contributor

Re: strtok_r return value..............

What you need and what strtok() or _r() do are two different things --- and the functions are working as designed. If either worked as you say you wanted then you would not be able to tell if you were at the end of the source string or simply between two adjacent tokens. What you should be testing for is that the ptr returned != NULL and, if so, that strlen(ptr) > 0.

You are really confusing a NULL pointer and a null string -- and they aren't the same thing at all.

If it ain't broke, I can fix that.
Tnameh
Occasional Advisor

Re: strtok_r return value..............


Thanks for the reply.
#include
#include

int main ()
{
char str[] ="This:is::::::abc";
char * pch;
int i=0;
printf ("Splitting string \"%s\" in tokens:\n",str);
pch = strtok (str,":");
while (pch != NULL)
{
pch = strtok(NULL,":");
if( pch !=NULL) {
if(strlen(pch) > 0)
printf(" %d %s\n",i++,pch);
}
else
printf(" %d \n",i++);
}
return 0;
}

What i need is when i parse string, i need sequential data,even strlen(pch) is zero.
something like
1 This
2 is
3
4
5
6
7
8 abc

Hope i am clear. Please let me know how can i solve this.
regards
Hemant
A. Clay Stephenson
Acclaimed Contributor

Re: strtok_r return value..............

OK, I see what you are trying to do now. Strtok skips past any adjacent tokens. You will need to either make your own function to parse it like you want to or use something like sscanf but that would not be a very safe choice.
If it ain't broke, I can fix that.
Peter Nikitka
Honored Contributor

Re: strtok_r return value..............

Hi,

what to you mean by that:
>>
What i need is when i parse string, i need sequential data,even strlen(pch) is zero.
<<

Using this source


#include
#include

int main (int argc, char** argv)
{
char*str = argv[1];

char * pch;
int i=0;

if (argc <2) return(1);
printf ("Splitting string \"%s\" in tokens:\n",str);
pch = strtok (str,":");
/* so you get 0 if no string is found */
if (pch) i++;
printf("%d %s\n",i,str);

if(!pch) return(0);

while (pch = strtok(NULL,":"))
{
i++;
if(strlen(pch)) printf("%d %s\n",i,pch);
}
return 0;
}

I do not get any empty fields:
./abc a:b and
./abc a::b
will give the same output.


Is that what you want to differ?

mfG Peter
The Universe is a pretty big place, it's bigger than anything anyone has ever dreamed of before. So if it's just us, seems like an awful waste of space, right? Jodie Foster in "Contact"
Peter Nikitka
Honored Contributor
Solution

Re: strtok_r return value..............

Ok,

just saw Clay's response - so if you want empty field information:


#include
#include

int main (int argc, char** argv)
{
char*str = argv[1];

char *pch, *last;
int i=0,j,d,l;

if (argc <2) return(1);
printf ("Splitting string \"%s\" in tokens:\n",str);
pch = strtok (str,":");
/* so you get 0 if no string is found */
if (pch) i++;
printf("%d %s\n",i,str);

if(!pch) return(0);

l = strlen(pch);
last = pch;

while (pch = strtok(NULL,":"))
{
d = pch - last;
i++;

/*
if((d-l)>1) printf("%d empty fields\n",d-l-1);
*/
for(j=d-l;j>1;j--) printf("%d\n",i++);

l=strlen(pch);
if(l) printf("%d %s\n",i,pch);
last=pch;
}
return 0;
The Universe is a pretty big place, it's bigger than anything anyone has ever dreamed of before. So if it's just us, seems like an awful waste of space, right? Jodie Foster in "Contact"
Dennis Handly
Acclaimed Contributor

Re: strtok_r return value, empty fields

I guess mine is is very similar to Peter's.

#include <stdio.h>
#include <string.h>
int main() {
    char buffer[80];
    static const char sep[] = ":";
    char *brkt, *word, *save;
    strcpy(buffer, "This::abc:");
    word = strtok_r(buffer, sep, &brkt);
    printf("word: %s\n",word);
    save = word + strlen(word)+1;
    word = strtok_r(NULL, sep, &brkt);
    /* dump out empties for each byte diff */
    for (;save < word; ++save)
       printf("empty string\n");
    printf("word: %s\n",word);
    return 0;
}

Tnameh
Occasional Advisor

Re: strtok_r return value..............

Thanks a lot for all the replies, but what in case if i have string something like
"abc::::def::::"

how to handle this situation. I guess all program will fail in this condition.

any clue how to handle this.
Peter Nikitka
Honored Contributor

Re: strtok_r return value..............

Hi,

dealing with trailing empty fields where left as an execise ...; (leading (multiple) empty fields can be done in a similar manner).
My solution stores the value of the initial string length and loops over the part skipped by strtok after its loop:

#include
#include

int main (int argc, char** argv)
{
char*str = argv[1];

char *pch, *last;
int i=0,j,d,l,ll;

if (argc <2) return(1);
printf ("Splitting string \"%s\" in tokens:\n",str);
/* to get traling empty fields: */
ll=strlen(str);

pch = strtok (str,":");
/* so you get 0 if no string is found */
if (pch) i++;
printf("%d %s\n",i,str);

if(!pch) return(0);

l = strlen(pch);
last = pch;

while (pch = strtok(NULL,":"))
{
d = pch - last;
i++;

/*
if((d-l)>1) printf("%d empty fields\n",d-l-1);
*/
for(j=d-l;j>1;j--) printf("%d\n",i++);

l=strlen(pch);
if(l) printf("%d %s\n",i,pch);
last=pch;
}
/*
printf("trailing empty fields: %d\n", str+ll-last-l);
*/
for(j=0;jreturn 0;
}


mfG Peter
The Universe is a pretty big place, it's bigger than anything anyone has ever dreamed of before. So if it's just us, seems like an awful waste of space, right? Jodie Foster in "Contact"
Sandman!
Honored Contributor

Re: strtok_r return value..............

Hi Haihemant,

As Clay pointed out:
>You will need to either make your own function to parse it like you want to or >use something like sscanf but that would not be a very safe choice.

In case of variable-format strings your best bet will be to write your own function in order to parse/display individual fields as strtok will not be able to parse and display variable format strings that need to output NULL for zero length fields:

"::abc::def" or "::abc::def:" or "abc::def" or "abc::def::"