gpt4 book ai didi

c++ - 在 C++ 中读取字符串数组 HDF5 属性

转载 作者:太空宇宙 更新时间:2023-11-04 13:02:06 24 4
gpt4 key购买 nike

我有可用的 C++ 代码,它使用存储在属性中的列名写入 HDF5 数据。我可以在 Matlab 中成功读取和处理数据,但我正在尝试创建一个 C++ 阅读器。它读取数据正常,但是当我尝试读取标题时,我只得到第一列名称。
属性创建过程的片段如下所示:

    // Snip of working code during the creation/recording of a DataSet named mpcDset:

std::vector<std::string> lcFieldnames;
lcFieldnames.clear();
lcFieldnames.push_back("Field1");
lcFieldnames.push_back("Field2");
lcFieldnames.push_back("Field3");

uint lnMaxStringLen = 10;
uint lnNumFields = lcFieldnames.size();
char* lpnBuffer = new char[lnNumFields*lnMaxStringLen];
memset((void*)lpnBuffer,0,lnNumFields*lnMaxStringLen);

int lnCount = 0;
for (auto& lnIndex : lcFieldnames)
{
lnIndex.copy(lpnBuffer + (lnCount *
lnMaxStringLen), lnMaxStringLen -1);
lnCount++;
}
hsize_t lpnHwriteDims[] = { lnNumFields, lnMaxStringLen };

H5::DataSpace lcAdspace(2, lpnHwriteDims, NULL);
H5::Attribute lcAttr = mpcDset->createAttribute(
std::string("header"),
H5::PredType::NATIVE_CHAR, lcAdspace);
lcAdspace.close();
lcAttr.write(H5::PredType::NATIVE_CHAR, lpnBuffer);
lcAttr.close();

delete [] lpnBuffer;

有问题的代码如下所示:

 // In another program, given an opened DataSet named mpcDset:

H5::Attribute lcAttr = mpcDset.openAttribute("header");

H5::DataType lcType = lcAttr.getDataType();

hsize_t lnSize = lcAttr.getStorageSize();

char* lpnBuffer = new char[lnSize];
lcAttr.read(lcType, lpnBuffer);
for (uint i=0;i<lnSize; i++)
{
std::cout<<lpnBuffer[i];
}
std::cout<<std::endl;
delete [] lpnBuffer;
lcAttr.close();

lnSize 对于所有三个字段都足够大(通过检查),但仅输出“Field1”。关于我做错了什么有什么建议吗?

最佳答案

就我个人而言,要在 C++ 中创建一个字符串列表属性,我会执行以下操作(类似的操作):这段代码会写一个属性,它是 3 个字符串,然后它会读取每个字符串。

#include "H5Cpp.h"    
#ifndef H5_NO_NAMESPACE
using namespace H5;
#endif
#include <iostream>
#include <string>
#include <vector>
using std::string;
using std::vector;
using std::cout;
using std::endl;

int main(int argc, char *argv[])
{
//WRITE ATTRIBUTE
{
try
{
//Example:
//Suppose that in the HDF5 file: 'myH5file_forExample.h5' there is a dataset named 'channel001'
//In that dataset we will create an attribute named 'Column_Names_Attribute'
//That attribute is a list of strings, each string is of variable length.

//The data of the attribute.
vector<string> att_vector;
att_vector.push_back("ColName1");
att_vector.push_back("ColName2 more characters");
att_vector.push_back("ColName3");

//HDF5 FILE
H5::H5File m_h5File;
m_h5File = H5File("myH5file_forExample.h5", H5F_ACC_RDWR); //Open file for read and write
DataSet theDataSet = m_h5File.openDataSet("/channel001"); //Open dataset
H5Object * myObject = &theDataSet;

//DATASPACE
StrType str_type(PredType::C_S1, H5T_VARIABLE);
const int RANK = 1;
hsize_t dims[RANK];
dims[0] = att_vector.size(); //The attribute will have 3 strings
DataSpace att_datspc(RANK, dims);

//ATTRIBUTE
Attribute att(myObject->createAttribute("Column_Names_Attribute" , str_type, att_datspc));

//Convert the vector into a C string array.
//Because the input function ::write requires that.
vector<const char *> cStrArray;
for(int index = 0; index < att_vector.size(); ++index)
{
cStrArray.push_back(att_vector[index].c_str());
}

//WRITE DATA
//att_vector must not change during this operation
att.write(str_type, (void*)&cStrArray[0]);
}
catch(H5::Exception &e)
{
std::cout << "Error in the H5 file: " << e.getDetailMsg() << endl;
}
}

//READ ATTRIBUTE
{
try
{
//HDF5 FILE
H5::H5File m_h5File;
m_h5File = H5File("myH5file_forExample.h5", H5F_ACC_RDONLY); //Open file for read
DataSet theDataSet = m_h5File.openDataSet("/channel001"); //Open dataset
H5Object * myObject = &theDataSet;

//ATTRIBUTE
Attribute att(myObject->openAttribute("Column_Names_Attribute"));

// READ ATTRIBUTE
// Read Attribute DataType
DataType attDataType = att.getDataType();
// Read the Attribute DataSpace
DataSpace attDataSpace = att.getSpace();
// Read size of DataSpace
// Dimensions of the array. Since we are working with 1-D, this is just one number.
hsize_t dim = 0;
attDataSpace.getSimpleExtentDims(&dim); //The number of strings.

// Read the Attribute Data. Depends on the kind of data
switch(attDataType.getClass())
{
case H5T_STRING:
{
char **rdata = new char*[dim];
try
{
StrType str_type(PredType::C_S1, H5T_VARIABLE);
att.read(str_type,(void*)rdata);
for(int iStr=0; iStr<dim; ++iStr)
{
cout << rdata[iStr] << endl;
delete[] rdata[iStr];
}
delete[] rdata;
break;
}
catch(...)
{
for(int iStr=0; iStr<dim; ++iStr)
{
delete[] rdata[iStr];
}
delete[] rdata;
throw std::runtime_error("Error while reading attribute.");
}

throw std::runtime_error("Not valid rank.");
break;
}

case H5T_INTEGER:
{
break;
}

case H5T_FLOAT:
{
break;
}

default:
{
throw std::runtime_error("Not a valid datatype class.");
}
}
}
catch(H5::Exception &e)
{
std::cout << "Error in the H5 file: " << e.getDetailMsg() << endl;
}
catch(std::runtime_error &e)
{
std::cout << "Error in the execution: " << e.what() << endl;
}
}

return 0;
}

写入操作的结果,在 HDFview 程序中看到:

The properties of the attribute

关于c++ - 在 C++ 中读取字符串数组 HDF5 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43722194/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com