我想将以null结尾的字符串复制到另一个位置,并想知道复制的字符串有多长。效率至关重要。有strcpy
函数可以实现这一点,但它不会返回实际复制的字符数。
当然,我可以通过以后简单地调用strlen
来检测复制字符串的长度来找到它,但这意味着第二次再次遍历字符串中的字符,尽管strcpy
必须跟踪它复制的字符数。出于性能原因,我不想进行这样的第二次遍历。
我知道使用简单的char-by-char副本编写自己的strcpy
很容易,但我认为标准库可能会使用魔术,这使得strcpy
比一个天真的char-by更快-char实施。
那么,strcpy
的最佳方法是什么,并且在不再遍历字符串的情况下接收复制字符的数量?
答案 0 :(得分:7)
许多系统支持stpcpy
,它返回指向目标末尾的指针。您可以减去原始目标指针,这样您就可以获得长度。
答案 1 :(得分:3)
如果你真的需要这个,你可以很容易地编写自己的:
unsigned int lenstrcpy(char dest[], const char source[]) {
unsigned int i = 0;
while ((dest[i] = source[i]) != '\0') {
i++;
}
return i;
}
答案 2 :(得分:3)
我会用sprintf
来完成这项工作:
size_t len_strcpy(char *dest, char const *src) {
return sprintf("%s", dest, src);
}
很难猜测这是否会比使用strcpy
后跟strlen
更慢或更快。以微软编译器为例,他们最近在sprintf
的实现方面做了一些工作,所以(在英特尔上)它使用向量指令并且运行得非常快。对于旧版本的编译器,strcpy
/ strlen
获胜的机会会更大。
答案 3 :(得分:2)
标准C库不提供满足您需求的功能,因此您需要自己编写。幸运的是,它并不太复杂:
'Could not find ndk-build. Please install Android NDK' and Could not find android. Please install android SDK
上述实现是从K& R解除的,只有一个小修改:它不是直接使用size_t StrCpyLen(char *dest, const char *src) {
const char *s = src;
while ((*dest++ = *s++))
;
return s - src - 1;
}
,而是在运行循环之前复制,因此可以通过减去原始{{}来确定长度。 1}}一旦循环完成。
答案 4 :(得分:2)
我会尝试这一点 - 使用strlen()
然后memcpy()
但是像往常一样,当你的速度是你的目标时,你最好为目标平台测试它,因为在理论上可能有很多因素很难计算
将memcpy()
添加到Ben的speed test
在gcc 5.1.0上使用-O1结果是:
对于part1和part3的-O2结果几乎没有改变,但是part2改变了很多:
看起来像-O2优化编译器消除了对strlen()
的额外调用并使用了缓存值。