簡體   English   中英

為什么 strtok 對 const 發出警告?

[英]Why does strtok warn against a const?

我對 strtok 的理解是它返回一個指向 char 數組(char*)中第一個分隔符的指針。

我收到反對 const char* 作為參數的警告,但我不明白為什么這很重要 - strtok 根本不修改參數。

我的理解:

const char* mystring = "this, is a test";
char* endstring = strtok(mystring, ',');
char* newstring = strdup(endstring);
printf("started with: %s\n now have: %s\n", mystring, newstring);

應該打印

started with: this, is a test 
now have: , is a test

mystring 完全沒有受到影響,當然,我有一個指向它的中途的指針,但這沒關系。 那么為什么 strtok 抱怨我給它發送一個 const char* 呢?

function strtok()修改了它的參數。 返回的指針在您的原始字符串內。 分隔符(在您的情況下, )被替換為\0字符。 strtok()的下一個調用不應有字符串參數,而是NULL指針。 不過要小心: strtok()將一串分隔符作為參數,而不是單個字符:

strtok(s, ','); //undefined behavior, interprets the ASCII value ',' as an address
strtok(s, ","); //correct

實際發生了什么?

讓我們分析一下這個字符串:

"Hello magic world!\0"

我們如何使用strtok()呢?

char s[] = "Hello magic world!"
char* first = strtok(s, " ");
char* second = strtok(NULL, " ");
char* third = strtok(NULL, " ");

讓我們看看它被標記化后的字符串:

"Hello\0magic\0world!\0"
 ^      ^      ^
 |      |      |
first  second  third

可以看到這3個指針可以作為常規的null終止字符串使用,但是在這個過程中原始字符串被破壞了。 puts(s)現在只打印“你好”。

printf("%s\n", s);
printf("%s %s %s\n", first, second, third);

Output:
Hello
Hello magic world!

strtok()不能用於字符串文字而不導致潛在的未定義行為。 當您將const char *作為第一個參數傳遞時,編譯器應該發出警告。 恕我直言,這是一個設計缺陷,這不被視為錯誤。

您的代碼還有另一個問題:您傳遞了一個字符常量','作為第二個參數,而不是字符串","

要解析常量字符串,您可以使用strspnstrcspn來返回多個字符,而無需修改字符串參數。

這是一個例子:

const char *mystring = "this, is a test";
size_t n1 = strcspn(mystring, ",");
size_t n2 = strspn(mystring + n1, ",");
char *newstring = strndup(mystring, n1);
printf("started with: %s\n rest of the string: %s\n", newstring, mystring + n1 + n2);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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