【问题标题】:How can I write vector<unsigned char> to file, followed by an unsigned int如何将 vector<unsigned char> 写入文件,后跟 unsigned int
【发布时间】:2016-01-12 06:59:30
【问题描述】:

我必须将 5 个 unsigned char 向量 (data_length=5) 分组。在组的末尾,我想添加一个 ID 组并将它们(组数据+其 ID)写入文件。在哪个组 ID 类型 integer。我按照以下代码执行该任务。这是正确的吗? 下图显示了我正在服用的东西

#define random(x) (rand()%x)
std::ofstream filewrite("abc.raw", std::ios::out | std::ofstream::binary);
unsigned int iter = 0;
unsigned int data_length=5;
unsigned int ID_data=0;
//-------------Write data-------------//
while (iter<10){
    vector<unsigned char> vec_data;
    for (unsigned int i=0;i<data_length;i++){
        vec_data.push_back(random(256))
    }           
    std::copy(vec_data.begin(), vec_data.end(), std::ostreambuf_iterator<char>(filewrite));
    //Write ID_data after vec_data
    filewrite.write(reinterpret_cast<const char *>(&ID_data), sizeof(ID_data));
    ID_data++;
    iter++;
}
filewrite.close();

另外,我想将数据提取到没有组 ID 的向量中。这是我从上述文件中提取数据的代码,但它不会删除 ID 组。你能帮我删除它吗?

//-------------Read data-------------//
std::ifstream file("abc.raw", std::ios::binary);
// Stop eating new lines in binary mode!!!
file.unsetf(std::ios::skipws);

// get its size:
std::streampos fileSize;

file.seekg(0, std::ios::end);
fileSize = file.tellg();
file.seekg(0, std::ios::beg);

// reserve capacity
std::vector<unsigned char> vec;
     vec.insert(vec.begin(),
std::istream_iterator<unsigned char>(file),
std::istream_iterator<unsigned char>());

【问题讨论】:

  • 如果这段代码有效,那么我想你应该在代码审查部分询问它。
  • 不要解释发生了什么问题,而是提供观察结果。您的问题不清楚。
  • @MehrdadMomeny 问题的前半部分不清楚它是否有效。第二部分肯定没有按预期工作,所以此时Code Review 不合适。另外,我们不是“部分”:p
  • @Zak LOL,是的,section 不是正确的术语。 :)
  • 为什么random 是一个宏?此外,我仍然投票结束这个话题,因为缺少最小但完整的示例。请删除您的问题,然后研究发布指南,然后提出正确的问题。

标签: c++ file visual-studio-2013


【解决方案1】:

首先,您使用while,其中for 更易于阅读。顺便提一句。您不需要两个迭代变量。可以遍历ID_data

for( unsigned int ID_data = 0; ID_data < 10; ++ID_data ) {
    // ...
}

其次,您不需要生成一个永远不会重复使用的向量,然后编写元素。直接写值就好了。

for( unsigned int ID_data = 0; ID_data < 10; ++ID_data ) {
    for( unsigned int i = 0; i < data_length; i++ )
        filewrite.put(random(256));

    filewrite.write(reinterpret_cast<const char *>(&ID_data), sizeof(ID_data));
}

第二部分:你可以用两个迭代器实例化一个向量。

auto vec = std::vector<unsigned char>(std::istream_iterator<unsigned char>{file},
                                      std::istream_iterator<unsigned char>{});

但由于您只想读取 data_length 值,您可能更喜欢:

auto vec = std::vector<unsigned char>{};

while( file ) {
    for( unsigned int i = 0; i < data_length; i++ ) {
        char c;
        if( !file.get(c) )
            break;
        vec.push_back(static_cast<unsigned char>(c));
    }

    unsigned int ID_data;
    file.read(reinterpret_cast<const char *>(&ID_data), sizeof(ID_data));
    // we don't use ID_data here, so it will simply be ignored.
}

【讨论】:

  • 谢谢,但它有错误为 &std::basic_istream>::get(std::basic_streambuf> &, _Elem)': 无法将参数 1 从 'unsigned char' 转换为 'char & 和错误 C2664: 'std::basic_istream> &std::basic_istream>::read(_Elem *,std::streamsize)': 无法将参数 1 从 'const char *' 转换为 'char *' 我认为它必须是 file.read(reinterpret_cast(&ID_data), sizeof (ID_data));和字符 c;
  • 我相应地改变了我的答案。现在应该可以了。
【解决方案2】:

我不确定我是否正确理解了您的问题。由于我假设您在二进制写入方面遇到问题,因此我只为您提供一个向量的解决方案。您可以轻松修改它:

void Write( std::ostream& os, const std::vector< std::uint8_t >& v, const std::int32_t id )
{
  std::size_t len = v.size();
  os.write( (const char*)&len, sizeof len );
  for ( auto e : v )
    os.write( (const char*)&e, sizeof e );
  os.write( (const char*)&id, sizeof id );
}

void Read( std::istream& is, std::vector< std::uint8_t >& v )
{
  std::size_t len;
  is.read( (char*)&len, sizeof len );
  v.resize( len );
  for ( auto &e : v )
    is.read( (char*)&e, sizeof e );
  std::int32_t id;
  is.read( (char*)&id, sizeof id );
}

int main()
{
  // write
  {
    std::ofstream os( "abc.raw", std::ios::binary );
    if ( ! os )
      return -1;
    std::vector< std::uint8_t > v;
    v.push_back( 0x10 );
    v.push_back( 0x20 );
    v.push_back( 0x30 );
    Write( os, v, 0x123 );
  }

  // read
  {
    std::ifstream is( "abc.raw", std::ios::binary );
    if ( ! is )
      return -1;
    std::vector< std::uint8_t > v;
    Read( is, v );
  }

  //
  return 0;
}

【讨论】:

  • 第二个关于提取没有ID的原始数据的问题怎么样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 2012-03-07
  • 1970-01-01
相关资源
最近更新 更多