簡體   English   中英

strtok_r() 對 strtok() 做了哪些更改? 結果看起來還是一樣,它改變了原來的字符串

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM