Strtok and strtok_r

Source: Internet
Author: User
Tags strtok

Function Name: strtok
Function: searches for words separated by the delimiters specified in the second string.
Usage: char * strtok (char * str1, char * str2 );
Program example:

# Include <string. h>
# Include <stdio. h>

Int main (void)
{
Char input [16] = "abc, d ";
Char * p;

/* Strtok places a NULL terminator
In front of the token, if found */
P = strtok (input ,",");
If (p) printf ("% s/n", p );

/* A second call to strtok using a NULL
As the first parameter returns a pointer
To the character following the token */
P = strtok (NULL ,",");
If (p) printf ("% s/n", p );
Return 0;
}

The functions with _ r mainly come from UNIX. The difference between all functions with and without _ r is that functions with and without _ r are thread-safe, and r means reentrant and reentrant.

The result of the above program running is
Abc
D

1. strtok Introduction
As we all know, strtok can be based on user-provided delimiters (and separators can also be plural numbers, such as ",").
Splits a string until it encounters "/0 ".

For example, separator = "," string = "Fred, John, Ann"
Using strtok, we can extract the three strings "Fred", "John", and "Ann.
The above C code is

QUOTE: int in = 0;
Char buffer [] = "Fred, John, Ann"
Char * p [3];
Char * buff = buffer;
While (p [in] = strtok (buf ,","))! = NULL ){
I ++;
Buf = NULL ;}

As shown in the above Code, the first execution of strtok needs to take the address of the target string as the first parameter (buf = buffer), and then strtok needs to take NULL as the first parameter (buf = NULL ). The pointer column p [] stores the split result. p [0] = "John", p [1] = "John ", p [2] = "Ann", and the buf is changed to Fred/0 John/0Ann/0.

2. strtok Vulnerabilities
Let's change our plan: We have a string named "Fred male 25, John male 62, Anna female 16". We want to sort this string and input it to a struct,

QUOTE: struct person {
Char [25] name;
Char [6] sex;
Char [4] age;
}

To do this, one of the methods is to extract a string separated by commas (,) and then separate it with spaces.
For example, extract "Fred male 25" and split it into "Fred" "male" "25"
Below I wrote a small program to demonstrate this process:

QUOTE: # include <stdio. h>
# Include <string. h>
# Define INFO_MAX_SZ 255
Int main ()
{
Int in = 0;
Char buffer [INFO_MAX_SZ] = "Fred male 25, John male 62, Anna female 16 ";
Char * p [20];
Char * buf = buffer;

While (p [in] = strtok (buf ,","))! = NULL ){
Buf = p [in];
While (p [in] = strtok (buf ,""))! = NULL ){
In ++;
Buf = NULL;
}
P [in ++] = "***"; // represents Segmentation
Buf = NULL ;}

Printf ("Here we have % d strings/n", I );
For (int j = 0; j <in; j ++)
Printf ("> % S </N", P [J]);
Return 0;
}

The output of this program is:
Here we have 4 strings
> Fred <
> Male <
> 25 <
> *** <
This is just a small piece of data, not what we need. But why? This is because strtok uses a static (static) pointer to operate data. Let me analyze the running process of the above Code:

Red indicates the position pointed to by strtok's built-in pointer, and blue indicates strtok's string modification.

1. "Fred male 25, John male 62, Anna female 16" // External Loop

2. "Fred male 25/0 John male 62, Anna female 16" // enter the inner loop

3. "Fred/0 male 25/0 John male 62, Anna female 16"

4. "Fred/0 male/025/0 John male 62, Anna female 16"

5 "Fred/0 male/025/0 John male 62, Anna female 16" // inner loop Encounters "/0" back to outer loop

6 "Fred/0 male/025/0 John male 62, Anna female 16" // an External Loop Encounters "/0.

3. Use strtok_r
In this case, we should use strtok_r, strtok reentrant.
Char * strtok_r (char * s, const char * delim, char ** ptrptr );

Compared with strtok, we need to provide a pointer for strtok to operate, instead of using a matched pointer like strtok.
Code:

QUOTE: # include <stdio. h>
# Include <string. h>
# Define INFO_MAX_SZ 255
Int main ()
{
Int in = 0;
Char buffer [INFO_MAX_SZ] = "Fred male 25, John male 62, Anna female 16 ";
Char * p [20];
Char * buf = buffer;

Char * outer_ptr = NULL;
Char * inner_ptr = NULL;

While (p [in] = strtok_r (buf, ",", & outer_ptr ))! = NULL ){
Buf = p [in];
While (p [in] = strtok_r (buf, "", & inner_ptr ))! = NULL ){
In ++;
Buf = NULL;
}
P [IN ++] = "***";
Buf = NULL ;}

Printf ("here we have % d strings/N", I );
For (Int J = 0; JN <I; j ++)
Printf ("> % S </N", P [J]);
Return 0;
}

The output for this time is:
Here we have 12 strings
> Fred <
> Male <
> 25 <
> *** <
> JOHN <
> Male <
> 62 <
> *** <
> Anna <
> Female <
> 16 <
> *** <

Let me analyze the running process of the above Code:

The red color indicates the position pointed to by the outer_ptr of strtok_r,
Purple indicates the position pointed to by strtok_r inner_ptr,
The blue is strtok's modification to the string

1. "Fred male 25, John male 62, Anna female 16" // External Loop

2. "Fred male 25/0 John male 62, Anna female 16" // enter the inner loop

3. "Fred/0 male 25/0 John male 62, Anna female 16"

4 "Fred/0 male/025/0 John male 62, Anna female 16"

5 "Fred/0 male/025/0 John male 62, Anna female 16" // inner loop Encounters "/0" back to outer loop

6 "Fred/0 male/025/0 John male 62/0 Anna female 16" // enter the inner loop

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.