Strtok and strtok_r

Source: Internet
Author: User
Tags strtok
Strtok and strtok_r

Prototype: char * strtok (char * s, char * delim );

Function: Splits a string into a group of strings. S is the string to be decomposed, and delim is the separator string.

Note: during the first call, s points to the string to be decomposed, and then calls it again to set S to null.
Strtok searches for characters included in delim in S and replaces them with null ('/0') until the entire string is searched.

Return Value: A cut string starting from S. If no string is cut, null is returned.
All delim characters are filtered out, And the filtered characters are set as a cut node.

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", 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", P );

Return 0;
}

For the first call of a function, you need to set two counts. The result of the first cut returns the first ',' character string in the string, that is, the first time the above program outputs ABC.

The second call to this function strtok (null, "."), the first number of records is set to null. The result returns a cut based on the subsequent string, that is, the second Output D.

Functions with _ r mainly come from Unix or lower. The difference between all functions with and without _ r is that functions with and without _ r are thread-safe, and R means reentrant, which can be reentrant.

1. strtok Introduction
As we all know, strtok can be based on the user's cut character (the separator can also be a plural number, for example, "," at the same time).
Cut a string until "/0" is encountered ".

For example, the separator is "," string = "Fred, John, Ann"
Strtok can be used to 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 * Buf = buffer;
While (P [in] = strtok (BUF ,","))! = NULL ){
In ++;
Buf = NULL ;}

As shown in the above Code, the first time you run strtok, you need to take the address of the target string as the first batch number (BUF = buffer), and then strtok needs to take null as the first batch number (BUF = NULL ). The P [] pointer column stores the cut result. P [0] = "John", P [1] = "John ", P [2] = "Ann", and Buf becomes 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 achieve this, one method is to extract a string that is "," cut, and then cut it by "" (Space.
For example, extract "Fred male 25" and cut 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 ++] = "***"; // performance Cutting
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 execution process of the above Code:

The red color indicates the position pointed to by strtok's built-in pointer, and the blue color indicates strtok's change 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, Anna female 16" // an External Loop Encounters "/0" and the execution ends.

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 execution 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 change 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

Strtok and strtok_r

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.