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 |