2010-06-03 40 views
6

我正在使用以下代码搜索字符串中第一次出现的字符串。 但是,当角色太长或者我搜索的角色在很远的范围内时会花费一些时间,这会延迟其他操作。我怎样才能解决这个问题。代码在这里。查找字符串C语言中的字符

注:attrPtr是一个char *,它在很远的程度上保存对包含'"'字符的字符串的引用。

int position = 0; 

char qolon = '"';//character to search 

while (*(attrPtr + position++) != qolon); 

char* attrValue = NULL; 

attrValue = (char*)malloc(position * sizeof(char)); 

strncpy(attrValue, attrPtr, position-1); 

回答

22

strchr通常会稍快。另外,你需要检查一下strchr会为你处理的NUL终结符。

char *quotPtr = strchr(attrPtr, qolon); 
if(quotPtr == NULL) 
{ 
    ... // Handle error 
} 
int position = quotPtr - attrPtr; 
char* attrValue = (char*) malloc((position + 1) * sizeof(char)); 
memcpy(attrValue, attrPtr, position); 
attrValue[position] = '\0'; 

虽然我还没有测试过。

编辑:修正了一个。

+2

+1正确拼写NUL。 – 2010-06-03 04:58:03

+2

'NUL'是ASCII名字对象,C标准使用术语'空字符'。 – dreamlax 2010-06-03 05:30:59

+0

@Mathew感谢您的建议.... – boom 2010-06-03 13:22:49

2

它需要一个O(n)算法来搜索字符串中的字符。所以你不能做比你已经做的更好的事情。此外,请注意,您缺少memset(attrValue, 0, position);,否则您的字符串attrValue将不会以null结尾。

7

C有一个内置函数用于搜索字符串中的字符 - strchr()strchr()返回一个指向找到的字符的指针,而不是数组的位置,所以你必须从返回的指针中减去指向字符串开头的指针来获取它。你可以改写你的功能为:

char qolon = '"';//character to search 
char *found; 
char *attrVal = NULL; 

found = strchr(attrPtr, qolon); 

if (found) 
{ 
    size_t len = found - attrPtr; 

    attrVal = malloc(len + 1); 
    memcpy(attrVal, attrPtr, len); 
    attrVal[len] = '\0'; 
} 

这可能比你的原始速度快一个小的常数因子;然而,你不会得到一个数量级的加速。在无序字符串中搜索字符基本上是字符串长度的O(n)。

2

您发布的算法不能正确处理字符不存在于字符串中的情况。如果发生这种情况,它只会在内存中行进,直到它随机发生一个与你的字符匹配的字节,或者你吹过你分配的内存并获得段错误。我怀疑这就是为什么有时候它似乎“花太长时间”。

在C中,字符串通常以0(ascii nul或'\0')结尾。或者,如果您提前知道字符串的长度,则可以使用该字符串。

当然,有一个标准的C库例程完全是这样做的:strchr()。一个聪明的程序员可以使用它,而不是通过滚动自己的方式来防范错误。

4

两个重要的事情:

1)经常检查空终止搜索字符串时这样说:

while (*(attrPtr + position++) != qolon); 

应该是:

while (attrPtr[position] && attrPtr[position++] != qolon); 

(如果传递了一个字符串缺乏您搜索到的字符,它可能需要很长时间才能扫描所有内存)。编辑:我只是注意到有人在之前发布了这个,但我很好。我不同意,顺便说一句,strchr()是好的,但一个简单的循环,也检查终结者是好的(通常也有优势)。

2)注意strncpy()!

strncpy(attrValue, attrPtr, position-1); 

的strlen(attrPtr)> =(位置1),因此这将NOT空终止在attrValue字符串,这可能导致各种问题(包括在代码难以置信减速以后)。作为一个相关的说明,函数strncpy()是ERM,设计独特,所以如果你做这样的事情:

char buf[512]; 
strncpy(buf,"",4096); 

你会写4096个字节零的。

就个人而言,我在Win32上使用lstrcpyn(),而在其他平台上我有一个简单的实现。这对我来说更有用。