[英]What changes strtok_r() did over strtok()? Result still looks the same, it changes the original string
我被困在strtok()
上,為什么它會修改原始字符串……但后來有人告訴strtok_r()
不會那樣做……當我測試它時,我發現沒有任何變化。 strtok_r()
還修改了原始字符串。 在對strtok_r()
的調用結束時,原始字符串已更改。
變量有什么用 - char* rest = str
這是我的代碼。
#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "Tom Jerry Hary Potter";
char* token;
char* rest = str;
printf("\n\nOriginal String before while loop: %s", str);
printf("\n\nOriginal String length before while loop: %lu\n\n", strlen(str));
while ((token = strtok_r(rest, " ", &rest)))
printf(" %s :", token);
printf("\n\nOriginal String after while loop: %s", str);
printf("\n\nOriginal String length after while loop: %lu\n\n", strlen(str));
return (0);
}
Output
Original String before while loop: Tom Jerry Hary Potter
Original String length before while loop: 21
Tom : Jerry : Hary : Potter :
Original String after while loop: Tom
Original String length after while loop: 3
卡在 strtok() 上,為什么它會修改原始字符串……但后來有人告訴 strtok_r() 不會那樣做……當我測試它時,我發現沒有任何變化。 strtok_r() 還修改了原始字符串。 在調用 strtok_r() 結束時,原始字符串已更改。
這不是真的。 strtok_r(3)
確實更改了原始字符串,就像strtok(3)
之前所做的那樣,它的不同之處在於接受您的指向char *
的指針,以存儲信息(找到最后一個字符串時的位置)需要在調用之間使用,因此它可以從不同的線程重新進入,使 function 可重入。
Strtok 是一個古老的 function,早於 C 的時代。它修改原始字符串以避免使用動態分配的 memory,這更快,但如果你想保留原始字符串,你可以隨時調用strdup(3)
原始字符串,對得到的副本進行操作,完成后返回free(3)
使用的memory。
無論如何,即使您在本地 memory 分配的緩沖區中使用strtok(2)
,它仍然是不可重入的,因為它使用全局 static 數據來記住它正在解析的字符串上的 position,因此它可以在它停止的地方繼續得到下一個substring。如果你想在另一個循環中使用strtok(3)
,或者你想在遞歸過程中遞歸地重新進入它,那么你必須切換到_r
后綴的那個,否則你會丟失指針在外部調用中調用內部循環strtok()
。 例如:
char buffer[] = "root:0:0:x:System Administrator,Administrators Dept.,5742,+300 40 86 26:/root:/bin/sh";
/* look for password fields */
for(p = strtok(string, ":"); p; p = strtok(NULL, ":")) {
/* separate items with commas */
for (q = strtok(p, ","); q; q = strtok(NULL, ",")) {
.... /* the last call to strtok(NULL, ",") broke the point where
* the first call to strtok(NULL, ":") was looking at, in the
* outer loop. */
您需要更改為:
char *p1;
for(p = strtok_r(string, ":", &p1); p; p = strtok_r(NULL, ":", &p1)) {
char *p2;
for (q = strtok_r(p, ",", &p2); q; q = strtok_r(NULL, ",", &p2)) {
.... /* nothing breaks, if p1 and p2 are different variables. */
使用strdup()
的示例可能是:
char *p1, *working_string = strdup(original_string);
for(p = strtok_r(workin_string, ":", &p1); p; p = strtok_r(NULL, ":", &p1)) {
char *p2;
for (q = strtok_r(p, ",", &p2); q; q = strtok_r(NULL, ",", &p2)) {
.... /* nothing breaks, if p1 and p2 are different variables. */
}
}
...
free(working_string); /* or whenever you feel it can be freed */
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.