例如,achar *p指向 中的第一個字符"there is so \0ma\0ny \0 \\0 in t\0his stri\0ng !\0\0\0\0",如何Strrchr()找到最后一次出現的空字符?
出現以下問題:
=>停止回圈取決于什么條件!
=>我認為在所有情況下它都會嘗試訪問下一個記憶體區域以檢查其條件?在某些時候繞過字串邊界,UB!那么安全嗎!
如果我錯了,請隨時糾正我!
uj5u.com熱心網友回復:
正如評論中所解釋的那樣,這非常簡單。第一個 \0是 C 字串中的最后一個也是唯一一個。
所以如果你寫
char *str = "there is so \0ma\0ny \0 \\0 in t\0his stri\0ng !\0\0\0\0";
char *p = strrchr(str, 's');
printf("%s\n", p);
它會列印
so
因為strchr會在“so”中找到“s”,這是你給它的字串中的最后一個“s”。并且(回答你的具體問題)如果你寫
p = strrchr(str, '\0');
printf("%d %s\n", (int)(p - str), p 1);
它會列印
12 ma
證明strchr找到了第一個 \0。
很明顯,這str是一個長字串,其中嵌入了一些\0's。但是,在 C 中,沒有“嵌入\0's 的字串”這樣的東西。根據定義,C 字串不可能包含嵌入的\0. 根據\0定義,第一個結束字串。
還有一點。您曾提到,如果您要“訪問下一個記憶體區域”,您將“在某些時候繞過字串邊界,UB!” 你是對的。在我的回答中,當我說
p = strrchr(str, '\0');
printf("%d %s\n", (int)(p - str), p 1);
在這里,p指向strrchr認為是字串結尾的東西,所以當我計算p 1并嘗試使用 列印它時%s,如果我們不知道更好,看起來我確實誤入了未定義的行為。在這種情況下,當然是安全的,因為我們確切地知道第一個\0. 但如果我要寫
char *str2 = "hello";
p = strrchr(str2, '\0');
printf("%s\n", p 1); /* WRONG */
那么我肯定會超越邊緣。
uj5u.com熱心網友回復:
“字串”、“字符陣列”和“char* 指標”之間存在差異。
- AC 字串是由空字符終止的多個字符。
- 字符陣列是定義的字符數。
- char* 指標在技術上是指向單個字符的指標,但通常用于標記 C 樣式字串中的一個點。
您說您有一個指向字符 ( char*p)的指標,其值為*pis 't',但您認為 *p 是 C 樣式字串的第一個字符
"there is so \0ma\0ny \0 \\0 in t\0his stri\0ng !\0\0\0\0"。
正如其他人所說,因為你說這是一個 C 風格的字串,你不知道它的長度,那么后面的第一個空值p將標記字串的結尾。
如果這是一個字符陣列,char str[40]那么您可以通過從陣列的末尾向開頭回圈來找到最后一個空值,for (i=39; i>=0; i--)但是您不知道長度,因此這將不起作用。
希望有幫助,如果我誤入 C ,請原諒我,自從我使用 C 以來已經 25 年了 :)
uj5u.com熱心網友回復:
在您提出的情況下,您永遠無法知道您找到的空字符是否是最后一個,因為您無法保證字串的結尾。由于它是一個 c 字串,因此可以保證該字串以 '\0' 結尾,但是如果您決定超出這個范圍,您將無法知道您正在訪問的記憶體是否屬于您。從陣列中訪問記憶體具有未定義的行為,因為您可以僅訪問記憶體中屬于您的下一個物件,或者您可以觸摸未分配的記憶體,但它的塊仍然屬于您的行程,或者您可以嘗試觸摸一個完全不屬于你的細分市場。只有第三個會導致 SIGSEGV。你可以看到這個問題來檢查分段錯誤而不會使你的程式崩潰,
字串具有結束字符是有原因的。如果您堅持在字串的多個位置使用 \0,您可以使用另一個字符終止,但請注意,所有庫函式仍會將第一個 \0 視為字串的結尾。
在你的字串中有多個 \0 被認為是一種不好的做法,也是一件非常糟糕的事情,所以如果可以的話,避免它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/356247.html
上一篇:比較char*的元素
下一篇:C 中的指標和地址
