如何以 STL 方式将文件中一定数量的字符复制到向量?

发布于 2024-09-25 16:46:33 字数 436 浏览 0 评论 0原文

如果我想将文件的内容复制到向量中,我可以这样做:

std::ifstream file("path_to_file");
std::vector<char> buffer(std::istream_iterator<char>(file), 
                         std::istream_iterator<char>());

我的问题是,如果我只想复制前 n 个字符,我该怎么做?

编辑我可以编写自己的copy,但是有没有办法仅使用现有组件来做到这一点?

If I want to copy the contents of a file to a vector, I can do it like that:

std::ifstream file("path_to_file");
std::vector<char> buffer(std::istream_iterator<char>(file), 
                         std::istream_iterator<char>());

My question is, how would I do this if I want to copy only the first n chars?

Edit I could write my own version of copy, but is there a way to do this using only existing components?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柠檬色的秋千 2024-10-02 16:46:33

正如 Alexander 指出的,最快的方法是

std::vector<char> buffer(n);
file.read(&buffer[0], n);

在 C++0x 中,您可以使用 buffer.data() 而不是 &buffer[0];如果n == 0,后者具有未定义的行为。

As Alexander points out, the fastest way would be

std::vector<char> buffer(n);
file.read(&buffer[0], n);

In C++0x, you can use buffer.data() instead of &buffer[0]; the latter has undefined behavior if n == 0.

远山浅 2024-10-02 16:46:33

正如 史蒂夫,这需要< code>copy_n(),由于疏忽,它不在当前的标准库中,但将在 C++1x 中。您可以轻松地自己实现一个,这是我认为正确的一个:

template<class InIt, class OutIt> 
OutIt copy_n(InIt src, OutIt dest, size_t n) 
{
  if (!n) return dest;
  *dest = *src;
  while (--n)
    *++dest = *++src;
  return ++dest; 
} 

请注意,std::copy_n() 假定输入迭代器能够传递 n 对象。从文件读取时,这可能会出现问题。


如果没有 std::copy_n(),您可以使用 std::generate_n

template< typename InIt >
struct input_generator {
  typedef std::iterator_traits<InIt>::value_type value_type;

  input_generator(InIt begin, InIt end) begin_(begin), end_(end) {}

  value_type operator()()
  {
    assert(it_ != end);
    return *it_++;
  }

  Init begin_;
  Init end_;
};


std::vector<char> buffer;
buffer.reserve(42);

std::generate_n( std::back_inserter(buffer)
               , 42
               , input_generator(std::istream_iterator<char>(file))
               , input_generator(std::istream_iterator<char>()) );

但是,我不认为这比直接从文件中读取 avakar 显示

As was noted by Steve, this would need copy_n(), which, due to an oversight, isn't in the current standard library, but will be in C++1x. You can implement one yourself easily, here's one I believe to be correct:

template<class InIt, class OutIt> 
OutIt copy_n(InIt src, OutIt dest, size_t n) 
{
  if (!n) return dest;
  *dest = *src;
  while (--n)
    *++dest = *++src;
  return ++dest; 
} 

Note that std::copy_n() presumes the input iterator to be able to deliver n objects. When reading from a file, this could be problematic.


Absent of std::copy_n(), you could use std::generate_n.

template< typename InIt >
struct input_generator {
  typedef std::iterator_traits<InIt>::value_type value_type;

  input_generator(InIt begin, InIt end) begin_(begin), end_(end) {}

  value_type operator()()
  {
    assert(it_ != end);
    return *it_++;
  }

  Init begin_;
  Init end_;
};


std::vector<char> buffer;
buffer.reserve(42);

std::generate_n( std::back_inserter(buffer)
               , 42
               , input_generator(std::istream_iterator<char>(file))
               , input_generator(std::istream_iterator<char>()) );

However, I don't see this as an advantage over reading directly from the file as avakar showed.

对风讲故事 2024-10-02 16:46:33

“STL方式”是使用copy_n,它是STL中的,但不是C++标准中的。

The "STL way" is to use copy_n, which is in the STL but not the C++ standard.

凶凌 2024-10-02 16:46:33
char *buffer = new char[n];
file.read(buffer,n);
std::vector<char> myVector
for (int i=0;i<n;i++) myVector.push_back(buffer[i]);
delete [] buffer;

// myVector now holds the first n bytes of file.

这可能不是最漂亮或最快的方法,但这是我会做的。

char *buffer = new char[n];
file.read(buffer,n);
std::vector<char> myVector
for (int i=0;i<n;i++) myVector.push_back(buffer[i]);
delete [] buffer;

// myVector now holds the first n bytes of file.

It may not be the prettiest or quickest way, but it is how I would do it.

や三分注定 2024-10-02 16:46:33

感谢@sbi,我忘记了 generate_n

file 内的 streambuf 有一个函数 snextc,一旦其隐式 this<,它就会返回下一个字符,将其限定为生成器函数。 /code> 参数已绑定。

generate_n( back_inserter( buffer ), 42,
            tr1::bind( tr1::mem_fn( &streambuf::snextc ), file.rdbuf() ) );

对于vector,直接读取即可。这对于 deque 或其他什么都有好处。

Credit due to @sbi, I forgot about generate_n.

The streambuf inside file has a function snextc which returns the next character, qualifying it as a generator function, once its implicit this argument is bound.

generate_n( back_inserter( buffer ), 42,
            tr1::bind( tr1::mem_fn( &streambuf::snextc ), file.rdbuf() ) );

For vector, just read directly. This is good for deque or whatever.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文