如何strcpy并返回复制的字符数?

时间:2015-12-21 19:12:30

标签: c++ string strcpy strlen

我想将以null结尾的字符串复制到另一个位置,并想知道复制的字符串有多长。效率至关重要。有strcpy函数可以实现这一点,但它不会返回实际复制的字符数。

当然,我可以通过以后简单地调用strlen来检测复制字符串的长度来找到它,但这意味着第二次再次遍历字符串中的字符,尽管strcpy必须跟踪它复制的字符数。出于性能原因,我不想进行这样的第二次遍历。

我知道使用简单的char-by-char副本编写自己的strcpy很容易,但我认为标准库可能会使用魔术,这使得strcpy比一个天真的char-by更快-char实施。

那么,strcpy的最佳方法是什么,并且在不再遍历字符串的情况下接收复制字符的数量?

5 个答案:

答案 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; 
}

Here is a live example.

答案 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

Demo.

上述实现是从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:62181 - 手动复制
  • part2:195093 - strcpy / strlen
  • part3:45568 - strlen / memcpy

对于part1和part3的-O2结果几乎没有改变,但是part2改变了很多:

  • part1:62234
  • part2:12129
  • part3:45565

看起来像-O2优化编译器消除了对strlen()的额外调用并使用了缓存值。