2014-09-02 9 views
5

Vorrei aggiungere append una stringa a un set di dati HDF5 di dimensione 1. Il seguente codice funziona per accodare i doppi al set di dati "doppio" nel file test-doubles.h5 ma il codice segfaults nella chiamata dataset.write(str, string_type, mspace, fspace):Come aggiungere una stringa al set di dati HDF5 con C++?

#include "H5Cpp.h" 
const int RANK = 1; 
H5::StrType string_type(H5::PredType::C_S1, H5T_VARIABLE); 

void append_double(H5::DataSet &dataset, double value) { 
    // dataspace 
    hsize_t dims[RANK] = { 1 }; 
    hsize_t maxdims[RANK] = { H5S_UNLIMITED }; 
    H5::DataSpace mspace(RANK, dims, maxdims); 

    H5::DataSpace space = dataset.getSpace(); 
    const hsize_t actual_dim = space.getSimpleExtentNpoints(); 

    // extend the dataset 
    hsize_t new_size[RANK]; 
    new_size[0] = actual_dim + 1; 
    dataset.extend(new_size); 

    // select hyperslab. 
    H5::DataSpace fspace = dataset.getSpace(); 
    hsize_t offset[RANK] = { actual_dim }; 
    hsize_t dims1[RANK] = { 1 }; 
    fspace.selectHyperslab(H5S_SELECT_SET, dims1, offset); 

    dataset.write(&value, H5::PredType::NATIVE_DOUBLE, mspace, fspace); 
} 

void append_string(H5::DataSet &dataset, string value) { 
    // dataspace 
    hsize_t dims[RANK] = { 1 }; 
    hsize_t maxdims[RANK] = { H5S_UNLIMITED }; 
    H5::DataSpace mspace(RANK, dims, maxdims); 

    H5::DataSpace space = dataset.getSpace(); 
    const hsize_t actual_dim = space.getSimpleExtentNpoints(); 

    // extend the dataset 
    hsize_t new_size[RANK]; 
    new_size[0] = actual_dim + 1; 
    dataset.extend(new_size); 

    // select hyperslab. 
    H5::DataSpace fspace = dataset.getSpace(); 
    hsize_t offset[RANK] = { actual_dim }; 
    hsize_t dims1[RANK] = { 1 }; 
    fspace.selectHyperslab(H5S_SELECT_SET, dims1, offset); 

    const char *str = value.c_str(); 
    dataset.write(str, string_type, mspace, fspace); 

} 

int main(int argc, char *argv[]) { 
    cout << "start" << endl; 
    { 
     H5::H5File h5_file("test-doubles.h5", H5F_ACC_TRUNC); 

     // create data space with unlimited dimensions for doubles 
     hsize_t doubles_dims[RANK] = { 0 }; 
     hsize_t doubles_maxdims[RANK] = { H5S_UNLIMITED }; 
     H5::DataSpace doubles_fspace(RANK, doubles_dims, doubles_maxdims); 

     // enable chunking for this dataset 
     H5::DSetCreatPropList cparms; 
     hsize_t chunk_dims[RANK] = { 1 }; 
     cparms.setChunk(RANK, chunk_dims); 

     // create dataset for doubles: 
     H5::DataSet d_dataset = h5_file.createDataSet("doubles", 
     H5::PredType::NATIVE_DOUBLE, doubles_fspace, cparms); 

     // append values to this dataset: 
     append_double(d_dataset, 1.0); 
     append_double(d_dataset, 2.0); 
     append_double(d_dataset, 3.0); 

     cout << "doubles written." << endl; 
    } 

    { 
     H5::H5File h5_file("test-strings.h5", H5F_ACC_TRUNC); 

     // create data space with unlimited dimensions for strings 
     hsize_t str_dims[RANK] = { 0 }; 
     hsize_t str_maxdims[RANK] = { H5S_UNLIMITED }; 
     H5::DataSpace str_fspace(RANK, str_dims, str_maxdims); 

     // enable chunking for this dataset 
     H5::DSetCreatPropList str_cparms; 
     hsize_t str_chunk_dims[RANK] = { 1 }; 
     str_cparms.setChunk(RANK, str_chunk_dims); 

     // create dataset for doubles: 
     H5::DataSet str_dataset = h5_file.createDataSet("strings", string_type, str_fspace, str_cparms); 

     // append strings to this dataset: 
     append_string(str_dataset, "test1"); 
     append_string(str_dataset, "test2"); 
     append_string(str_dataset, "test3"); 
     cout << "strings written." << endl; 
    } 

    cout << "all done." << endl; 
    return 0; 
} 

Grazie mille per il vostro aiuto!

+0

vedere la mia risposta qui sotto. Ma come si leggono i vettori di nuovo da HDF5? Mi piacerebbe una soluzione senza usare 'H5 :: DataSet :: read (H5std_string &, const DataType &)' ... Per favore rispondi [qui] (http://stackoverflow.com/questions/13814027/reading-a- string-from-hdf5-in-c/23878421? noredirect = 1 # comment50469238_23878421) – Walter

risposta

0

Io uso il seguente di scrivere una stringa in un file di H5:

void writeString(const H5::CommonFG& fg, const string& name, const string& s) 
{ 
    H5::StrType h5stringType(H5::PredType::C_S1, s.length() + 1); // + 1 for trailing zero 
    H5::DataSet ds = fg.createDataSet(name, h5stringType, H5::DataSpace(H5S_SCALAR)); 
    ds.write(s, h5stringType); 
    return; 
} 

int main() { 
    H5::H5File file; 
    file = H5::H5File(filename, H5F_ACC_EXCL); 
    H5::Group group = h5Model.createGroup("/test"); 
    writeString(group, "string name", "value"); 
} 
+0

La scrittura di una stringa non è un problema, il problema è di aggiungere una stringa a un set di dati con una dimensione H5S_UNLIMITED. – Frank

+0

Oh capisco. L'ho letto come si desidera "aggiungere al file". Puoi fornire informazioni di debug invece di dirlo solo segfaults? – Ela782

1

tutto funziona se si sostituisce

dataset.write(str, string_type, mspace, fspace); 

con

dataset.write(&str, string_type, mspace, fspace); 
Problemi correlati