在C语言中查找字符串中的字符

11
我正在使用以下代码在字符串中查找第一次出现的字符。 但是,当字符过长或我搜索的字符位于远处时,它需要一些时间,这延迟了其他操作。我该如何解决这个问题? 以下是代码。
注意: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);
5个回答

30

strchr通常会更快一些。此外,您需要检查NUL终止符,而strchr将为您处理。

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
"NUL"是ASCII的别名,C标准使用术语“空字符”。 - dreamlax
3
使用strncpy()没有意义,因为您已经知道要复制的确切字符数 - 您可以使用更有效的memcpy() - caf
不需要强制转换malloc()。sizeof(char)始终为1。 - Nyan

8

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)与字符串的长度成正比。


4

两个重要的事情:

1)在使用以下方式搜索字符串时,始终检查空终止符:

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

should be:

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

如果传入一个不包含所搜索字符的字符串,它可能需要很长时间来扫描所有内存。编辑:我刚刚注意到有人比我先发布了这个内容,但没关系。顺便说一下,strchr()是可以的,但是一个简单的循环也可以检查终止符,并且通常也有优势。

2)小心使用strncpy()!

strncpy(attrValue, attrPtr, position-1);

如果strlen(attrPtr)>=(position-1),那么这样就不会在attrValue中添加null终止符,这可能会导致各种问题(包括以后代码的极慢)。另外需要注意的是,strncpy()是独特设计的,如果你做了类似以下的事情:

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

您将会写入4096个字节的零。

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


2

在字符串中搜索一个字符需要一个 O(n) 的算法。所以你已经做得很好了,无法再有更好的方法。另外,请注意添加 memset(attrValue, 0, position); ,否则你的字符串 attrValue 将没有被正确地终止。


2
你发布的算法无法正确处理字符不存在于字符串中的情况。如果出现这种情况,它将继续在内存中查找,直到它随机找到一个与你的字符匹配的字节,或者超过了已分配的内存并导致段错误。我怀疑这就是为什么有时看起来会“花费太长时间”的原因。
在C中,字符串通常以0(ASCII NUL,或'\0')结尾。或者,如果您提前知道字符串的长度,则可以使用该长度。
当然,有一个标准的C库例程可以做到这一点:strchr()。明智的程序员应该使用它而不是冒着风险自己开发程序来避免错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接