簡體   English   中英

strlen沒有返回正確的長度

[英]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個相同值的序列,每個值都為零。 需要注意的是0x000 ,和'\\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.

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