我有一个char[]
缓冲区,其中包含从内存中读取的数据,这意味着此缓冲区中有多个Null,而不是只有一个Null在末尾终止。
char *addr = (char *)memmem(buff, strlen(buff), needle, strlen(needle));
我需要处理此字符串并搜索并替换某些内容。
为此,我想使用memmem()
,但不幸的是,它不起作用,因为缓冲区中有多个Null。
我试图用我认为不会出现的字符(Bell ASCII代码\ 7)替换缓冲区中的Null然后处理它,但这不起作用并破坏我的数据。
是否有另一种方法来处理具有多个Null的字符串?
答案 0 :(得分:4)
memmem
可用于执行此操作。但是,由于您的数据包含嵌入的空值,因此无法使用strlen
来计算长度。您需要分别跟踪长度。
char *addr = (char *)memmem(buff, buffLen, needle, needleLen);
答案 1 :(得分:2)
在你的char数组上使用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 Raabe指出的那样,不放弃了strlen
等经过试验的测试函数的优化和安全性,这可能是d_strlen
<的更好版本/ p>
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
}
答案 2 :(得分:0)
C字符串是由NUL终止的字符序列...根据定义,它不能包含多个NUL。你拥有的是更通用的东西,一块字符。为了处理任意的字符块,它们必须伴随一个长度 - 字符数的计数。鉴于您可以处理块而不关心它是否包含NUL。给定一个由指向某些字符和计数的指针组成的块,你可以使用count而不是strlen,所以
memmem(buff, buff_len, needle, needle_len);