strncpy相当于std :: copy

时间:2011-12-08 14:54:12

标签: c++ stl

STL提供 std :: copy 但是将它与具有固定大小的输出容器一起使用是很棘手的,因为输出迭代器没有边界检查

所以我发明了自己的东西,如下面的

template<class InputIterator , class OutputIterator>
void safecopy( InputIterator srcStart , InputIterator srcEnd , 
                    OutputIterator destStart , OutputIterator destEnd )
{
    while ( srcStart != srcEnd && destStart != destEnd )
    {
        *destStart = *srcStart;
        ++srcStart;
        ++destStart;
    }
}

int main()
{
    std::istream_iterator<char> begin(std::cin), end;       
    char buffer[3];

    safecopy( begin, end, buffer, buffer + 3 );     
    return 0;
}

问题:

  1. 我在这里重新发明轮子吗?是否有一个stl算法来做我想要的。
  2. 我的 safecopy 是否存在任何缺陷,是否适用于std :: copy适用的所有内容?

3 个答案:

答案 0 :(得分:5)

让我将评论推广到答案,所以我有更多的空间。

首先,您的实施看起来不错。

现在,为什么这不符合标准? (新标准增加了std::copy_n,但这也有所不同。*)

这样想:strncopy并不是一个“好”的想法;这不是一个可怕的想法。由于C没有任何动态数据结构,因此长度检查版本是您可以做的最好的。

但是在C ++中,这并不适合动态容器的一般概念:你很少想要覆盖一些元素,而是创建所有元素,你是std::copy加上std::inserterstrncpy是一个需要你预先分配目标数据结构的拐杖,但在C ++中我们可以做得比这更好。使用动态容器,迭代器和插入器,我们可以复制任何,而无需担心分配。

换句话说,您可能想到的任何抽象算法都应该有一个更好,更具体的方法来获取迭代器和迭代器范围(想想删除/擦除);算法的最终目标很少会产生一个受其他目标范围约束的输出范围。

总结:是的,你可以做到,但你可以做得更好。

*)虽然可以使用copy_n加上min的源和目标大小来创建有界副本。

答案 1 :(得分:1)

我会对您的实施做一个小调整。给它一个返回值。最终输出迭代器,或指示复制的元素数的整数。

我可以看到您的函数的主要用例是从输入流中读取固定大小的块,但您不知道它何时结束。如果它确实结束了,你需要某种方式来了解它,并且你需要知道在实际结束之前复制了多少元素。如果你知道复制了多少元素,并且它没有达到或超过输出范围的大小,那就是你知道它结束的方式。

答案 2 :(得分:0)

是。你又重新发明了轮子!

例如,您可以将std::copy用作:

std::copy(s.begin(), s.begin() + 3 , buffer);

而不是这个,

safecopy(s.begin(), s.end() , buffer, buffer + 3);

以这种方式使用std::copy并不比safecopy更安全。

或者更好的是{C ++ 11附带的std::copy_n

std::copy_n(s.begin(), 3, buffer);

即使参数不是随机访问迭代器,这也可以工作。


至于何时使用std::vector<char>,可以将其构造函数直接用作:

std::vector<char> v(s.begin(), s.end());

甚至不需要std::copy