2017-05-01 1 views
0

Je travaille sur du code C++ qui écrit des données HDF5 avec les noms de colonnes stockés dans un attribut. Je peux lire et traiter les données avec succès dans Matlab, mais j'essaie de créer un lecteur C++. Il lit les données d'accord, mais quand j'essaye de lire l'en-tête, je reçois seulement le nom de la première colonne.
Un extrait du processus de création d'attribut ressemble:Lecture d'un attribut HDF5 de matrice de chaînes en 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; 

Le code en question ressemble à:

// 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 est assez grand pour les trois champs (par l'inspection), mais seulement « Champ1 "est sortie. Des suggestions quant à ce que je fais mal?

Répondre

0

Personnellement, pour créer un attribut que c'est une liste de chaînes en C++ je fais comme suit (quelque chose de similaire): Ce code va écrire un attribut que ce soit 3 chaînes, puis il va lire chacune d'elles.

#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; 
} 

Résultat de l'opération d'écriture, vu dans le programme HDFview:

The properties of the attribute

+0

Merci @pablo_worker! Votre approche a résolu mon problème. –