2013-12-17 98 views
3

我有一個char[]緩衝區,其中包含從內存中讀取的數據,這意味着此緩衝區中有多個Null,並且不僅一個終止Null。使用C中包含多個空字符的字符串

char *addr = (char *)memmem(buff, strlen(buff), needle, strlen(needle)); 

我需要處理此字符串並搜索並替換某些內容。 爲此,我想使用memmem(),但不幸的是,它不起作用,因爲緩衝區內存在多個Null。

我試圖用一個我認爲不會出現的字符(Bell ASCII代碼\ 7)替換緩衝區中的Null,然後處理它,但這不起作用並破壞我的數據。

是否有另一種方法來處理有多個空值的字符串?

+0

向我們展示你的代碼 – Chinna

+3

AC串只有一個'\ 0',這是在其結束。包含任何值的char數組不是一個字符串,''函數不能用於它。 – mouviciel

+0

請不要在C中使用'memmem()'的返回值。 – unwind

回答

4

memmem可以用來做它。但是,由於您的數據包含嵌入的空值,因此無法使用strlen來計算長度。你需要分別跟蹤長度。

char *addr = (char *)memmem(buff, buffLen, needle, needleLen); 
+0

作品完美,謝謝! – user2212190

0

C字符串是由NUL終止的字符序列...根據定義,它不能包含多個NUL。你擁有的是更通用的東西,一大堆字符。要處理任意的字符塊,它們必須伴隨一個長度 - 字符數量的計數。鑑於您可以處理該塊,而不用擔心它是否包含NUL。鑑於由一個指向某個字符和計數的塊,你可以使用計數,而不是strlen的,所以

memmem(buff, buff_len, needle, needle_len); 
+0

@EliasVanOotegem我已經在C寫了35年了,並且在C標準委員會工作,我不同意你的認識論和學問,但我不會與你進行詳細的辯論。 –

2

,通過你自己也承認包含終止您的字符數組的使用strlen不會上班。您應該認識到strlen只是計算達到零終止符的點的數量。
順便提一句,這也是strncat的工作方式,所以你也不能使用這些功能。

您可以做的是保留一個int,您用它來跟蹤實際字符串的長度。
解決這一問題將是寫自己的d_strlen功能,始終確保您的緩衝區具有的其他方式零終止末字符:

size_t d_strlen(const char *in) 
{ 
    size_t len = 0; 
    while(!(in[len] == '\0' && in[len+1] == '\0')) ++len; 
    return len; 
} 

還是那句話:你buffer必備

char buff[100] = "this \0 string contains \0 terminators \0";//adds second \0 
printf("%d != %d\n", strlen(buff), d_strlen(buff));//yields 5 != 37 

:然後通過終止零,而不僅僅是一個終止

由於Frerich拉貝指出,要鬆散的優化和像strlen一個嘗試「N測試功能的安全性,這可能是一個更好的版本的d_strlen

size_t d_strlen(const char *in) 
{ 
    size_t len = 0; 
    while(strlen(in+len)) len += strlen(in+len) + 1; 
    return len ? --len : 0;//check for zero-length 
} 

然而,這要求strlen兩次,這是沒有意義的開銷,所以你可能會更好過寫這篇:

size_t d_strlen(const char *in) 
{ 
    size_t i, len = 0; 
    do 
    { 
     i = strlen(in+len);//get substring length 
     len += i + 1;//add to total length + 1 for \0 char 
    }while(i > 0); 
    return len > 1 ? len-2 : 0;//subtract 2, if possible, else return 0 
} 
+1

考慮到'strlen'通常是一個經過嚴格優化的函數,重用它可能會更高效(即對每個字符串重複地調用它並總結結果),而不是逐字節地迭代自己。 –

+0

@FrerichRaabe:公平點,增加了'd_strlen'函數的另一個實現,它使用'strlen' –

+0

Cool,+1,除了你爲每個子串調用'strlen(in + len)'兩次。 : - } –