2013-12-17 54 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)'两次。 : - } –