[英]strlen does not return the right length
我目前正在使用strlen
方法來計算此字符串的長度:
56 69 56 4F 74 65 63 68 32 00 2C 00 00 27 6F 23 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 11 BF 0C 0E 61 0C 4F 07 A0 00 00 00 04 10 10 87 01 01
主要的問題是它遇到00
時總是停止,我認為它與'\\0'
混淆了! 所以我想知道是否有替代這種方法,或者你有什么建議可以解決這個問題。
PS:我不確定問題是否重復我搜索了同樣的問題,但找不到令人滿意的答案!
編輯:
我的代碼:
unsigned char Response[269]={0x00};
unsigned char Response_PPSE[269];
for(i=0;i<=strlen(Response);i++)
sprintf(Response_PPSE+(2*i),"%02X",Response[i]);
strlen僅計算此字節的長度:56 69 56 4F 74 65 63 68 32 00
unsigned char Response[269]={0x00};
這會將Response
初始化為269個相同值的序列,每個值都為零。 需要注意的是0x00
, 0
,和'\\0'
都是同樣的事情。
strlen(Response)
這實際上是無效的,盡管一些編譯器可能允許它。 strlen
需要char*
類型的參數; Response
是一個unsigned char
數組,它被轉換為unsigned char*
類型的指針。 類型不兼容,並且沒有隱式轉換。 您應該收到編譯時警告(如果有,請在您的問題中包含警告)。
如果我們將Response
的定義更改為:
char Response[269] = {0x00};
然后strlen
調用變為有效 - 並將返回0
。 strlen
掃描第一個'\\0'
0'null字符 - 並且您已使用空字符填充Response
。
在問題的頂部,你說你有一個字符串:
56 69 56 4F 74 65 63 68 32 00 2C 00 00 27 6F 23 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 11 BF 0C 0E 61 0C 4F 07 A0 00 00 00 04 10 10 87 01 01
這與您向我們展示的代碼沒有任何關系。 它也含糊不清; 它是一個十六進制數字和空格的字符串: "56 69 56 ..."
,還是像"\\x56\\x69\\x56..."
? 如果56 69
序列用於表示數組的內容,請更新您的問題以顯示創建它的實際代碼。
最后:
for(i=0;i<=strlen(Response);i++)
sprintf(Response_PPSE+(2*i),"%02X",Response[i]);
在循環的每次迭代中調用strlen
可能效率很低。 strlen
每次都要掃描整個字符串以確定其長度。 一旦你解決了其他問題,你應該在循環之前調用strlen
並使用存儲的值。
但是 ,您可能不希望首先使用strlen
。 strlen
應用於字符串 。 “字符串”是由空字符( 0
, '\\0'
, 0x00
)終止的字符序列。 您似乎有一系列無符號字符,其中0x00
是有效值,而不是終止符。 您需要通過其他方式跟蹤長度,而不是使用strlen
來計算數組的長度。
00
和'\\0'
是一回事。
看起來您可以獲取數組的數組,而不是字符串的長度。 strlen
會將數組掃描到第一個空終止符。 對於任意數組沒有等價物,因此您需要自己跟蹤它。
到目前為止我看到的其他答案正在圍繞真正的問題跳舞。 這是你需要了解你正在處理什么樣的字符串 。
根據歷史慣例,C將字符串表示為空終止字符數組。 這是strlen
期望的那種字符串。 但是你的“字符串”包含空字節。 所以它不是一個以null結尾的字符串,而strlen
不會做你想要的。
更重要的是, strlen
非常危險 ,不應該在現代代碼中使用。 使用strlen很容易導致安全漏洞,並且如果您的程序使用strlen
來檢查通過網絡接收的響應,則可能會利用您的程序來實現拒絕或服務甚至遠程代碼執行。
如果你給它正確的尺寸限制,更安全的選擇是strnlen
。 關於正確的解決方案很難更准確,因為在你的例子中,正確的答案總是269,所以實際上沒有可變長度的字符串可以測量。
你的意思是數組的長度而不是響應的長度,所以你想要sizeof(Response)而不是strlen(Response) - 大概你知道響應是269字節長,因為這是卡協議定義的。
您還需要Response_PPSE為2 * 269 + 1個字節長,否則您的printf語句將在數組末尾運行。 並且您需要設置Response_PPSE [2 * 269] = 0以使其成為有效的以null結尾的字符串。
在我創建的應用程序中,我使用以下方法創建了一個自定義的“strlen”方法,以便正確計算長度,即使我的數據中間有空字節:
- 我們需要使用除了包含數據的char *,還有malloc的大小。 -I將以下參數傳遞給方法:第一個參數是char * str,第二個是malloc的大小。
-Method以相反的方式工作,從MAX內存地址(str +第二個參數的內存地址)到第一個內存大小,while循環遞減最大內存地址,直到達到第一個內存地址,但是這個while循環將中斷,以防萬一第一個非NULL / 0字符到達。
- 最后我們返回最后MAX存儲器地址和char *,+ 1的第一個存儲器地址的差值。
這是我的代碼:
size_t utils_strlen(const char * str, int max) {
const char * maxs;
maxs = str + max;
while(str<maxs) {
if(*maxs!=0) break;
maxs--;
}
return(maxs-str)+1;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.