2016-11-21 22 views
1

値がconst char *の可変長配列であるスカラー値属性を正常に作成しました。しかし、私はこの属性を読む方法を理解していません!これは私が属性を作成するために使用されるコードである値が可変長char *(つまりc_strings?)の配列であるHDF5スカラー属性を読み取る方法

:私はこのデータを読み取る方法を理解していない

HDF5 "d:\tmp\hdf5_tutorial\h5tutr_dset.h5" { 
GROUP "/" { 
DATASET "dset" { 
DATATYPE H5T_STD_I32BE 
DATASPACE SIMPLE { (4, 6)/(4, 6) } 
DATA { 
(0,0): 1, 7, 13, 19, 25, 31, 
(1,0): 2, 8, 14, 20, 26, 32, 
(2,0): 3, 9, 15, 21, 27, 33, 
(3,0): 4, 10, 16, 22, 28, 34 
} 
ATTRIBUTE "multi_filters" { 
DATATYPE H5T_VLEN { H5T_STRING { 
STRSIZE H5T_VARIABLE; 
STRPAD H5T_STR_NULLTERM; 
CSET H5T_CSET_ASCII; 
CTYPE H5T_C_S1; 
}} 
DATASPACE SCALAR 
DATA { 
(0): ("this is 0", "this is 1", "this is 2", "this is 3", "this is 4", "this is 5", "this is 6", "this is 7", "this is 8", "this is 9") 
} 
} 
} 
} 
} 

:ここ

void create_attribute_with_vector_of_strings_as_value() 
{ 
    using namespace H5; 

    // Create some test strings. 
    std::vector<std::string> strings; 
    for (int iii = 0; iii < 10; iii++) 
    { 
     strings.push_back("this is " + boost::lexical_cast<std::string>(iii)); 
    } 

    // Part 1: grab pointers to the chars 
    std::vector<const char*> chars; 
    for (auto si = strings.begin(); si != strings.end(); ++si) 
    { 
     std::string &s = (*si); 
     chars.push_back(s.c_str()); 
    } 
    BOOST_TEST_MESSAGE("Size of char* array is: " << chars.size()); 

    // Part 2: create the variable length type 
    hvl_t hdf_buffer; 
    hdf_buffer.p = chars.data(); 
    hdf_buffer.len = chars.size(); 

    // Part 3: create the type 
    auto s_type = H5::StrType(H5::PredType::C_S1, H5T_VARIABLE); 
    auto svec_type = H5::VarLenType(&s_type); 

    try 
    { 
     // Open an existing file and dataset. 
     H5File file(m_file_name.c_str(), H5F_ACC_RDWR); 

     // Part 4: write the output to a scalar attribute 
     DataSet dataset = file.openDataSet(m_dataset_name.c_str()); 

     std::string filter_names = "multi_filters"; 

     Attribute attribute = dataset.createAttribute(filter_names.c_str(), svec_type, H5S_SCALAR); 
     attribute.write(svec_type, &hdf_buffer); 
     file.close(); 
    } 

がh5dumpから見た属性を持つデータセットです。これまでに実験したコードは以下の通りです。それはコンパイルされますが、配列のサイズを既知の長さに固定してあり、可変長の文字列は空ですか?私はどこに間違っているのか誰にも示唆を持っていますか?特に、const char *の配列の長さを問い合わせる方法と、配列に含まれる実際のconst char * cstringを読み取るにはどうすればよいですか?あなたは、あなたが考えているものを実装するために特定の技術を使用する必要はありません場合は

void read_attribute_with_vector_of_strings_as_value() 
{ 
    using namespace H5; 

    std::vector<std::string> strings; 

    try 
    { 
     // Open an existing file and dataset readonly 
     H5File file(m_file_name.c_str(), H5F_ACC_RDONLY); 

     // Part 4: Open the dataset 
     DataSet dataset = file.openDataSet(m_dataset_name.c_str()); 

     // Atribute_name 
     std::string filter_names = "multi_filters"; 

     Attribute attribute = dataset.openAttribute(filter_names.c_str()); 
     size_t sz = attribute.getInMemDataSize(); 
     size_t sz_1 = attribute.getStorageSize(); 
     auto t1 = attribute.getDataType(); 
     VarLenType t2 = attribute.getVarLenType(); 
     H5T_class_t type_class = attribute.getTypeClass(); 
     if (type_class == H5T_STRING) 
      BOOST_TEST_MESSAGE("H5T_STRING"); 

     int length = 10; 
     std::vector<char*> tmp_vec(length); 
     auto s_type = H5::StrType(H5::PredType::C_S1, H5T_VARIABLE); 
     auto svec_type = H5::VarLenType(&s_type); 

     hvl_t hdf_buffer; 
     hdf_buffer.p = tmp_vec.data(); 
     hdf_buffer.len = length; 
     attribute.read(svec_type, &hdf_buffer); 
     //attribute.read(s_type, &hdf_buffer); 
     //attribute.read(tmp_vec.data(), s_type); 

     for(size_t x = 0; x < tmp_vec.size(); ++x) 
     { 
      fprintf(stdout, "GOT STRING [%s]\n", tmp_vec[x]); 
      strings[x] = tmp_vec[x]; 
     } 

     file.close(); 
    } 

答えて

0

することは、あなたが(SQLを考えて)簡単にHDFファイルを管理するための高レベルの言語であるHDFql(http://www.hdfql.comを)検討することができます。そうすることで、あなたが記述したHDFファイルを操作するすべての低レベルの詳細から軽減できます。 C++でHDFqlを使用すると、可変長charの配列を読み取ることは次のようになります。

// include HDFql C++ header file (make sure it can be found by the C++ compiler) 
#include <iostream> 
#include "HDFql.hpp" 

int main(int argc, char *argv[]) 
{ 

    // create an HDF file named "example.h5" and use (i.e. open) it 
    HDFql::execute("CREATE FILE example.h5"); 
    HDFql::execute("USE FILE example.h5"); 

    // create an attribute named "multi_filters" of type varchar of one dimension (size 5) 
    HDFql::execute("CREATE ATTRIBUTE multi_filters AS VARCHAR(5)"); 

    // insert (i.e. write) values "Red", "Green", "Blue", "Orange" and "Yellow" into attribute "multi_filters" 
    HDFql::execute("INSERT INTO multi_filters VALUES(Red, Green, Blue, Orange, Yellow)"); 

    // select (i.e. read) attribute "multi_filters" into HDFql default cursor 
    HDFql::execute("SELECT FROM multi_filters"); 

    // display content of HDFql default cursor 
    while(HDFql::cursorNext() == HDFql::Success) 
    { 
     std::cout << "Color " << HDFql::cursorGetChar() << " has a size of " << HDFql::cursorGetSize() << std::endl; 
    } 

    return 0; 

} 
関連する問題