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