Как хранить несколько массивов 2D-символов с помощью HDF5 на C ++?

Я хочу записать несколько массивов 2D-символов в один набор данных HDF5. В приведенном ниже коде есть два массива в структуре, и я помещаю (std :: copy) «привет» в один массив (name) и «привет» в другой (nicknams). Думал, что результат будет выглядеть:

(b'hello', b'hey')
(b'hello', b'hey')
(b'hello', b'hey')
(b'hello', b'hey')

Но когда я действительно запускаю код, результат выглядит так:

(b'hello', b'hey')
(b'(\xae\nVD\xae\nV\xff\xff', b'\xdc\x82\nV\x12\xd2\xfcv\x8f\x01')
(b'\x04', b'\x01') 
(b'$\xf8O', b'9\x08\xd2\xd5\xb4\xf8O')]

Поскольку самая первая строка выглядит нормально, я предполагаю, что что-то не так с нулевыми символами при записи массивов в набор данных. Я просмотрел примеры кодов на официальной веб-странице (https://support.hdfgroup.org/HDF5/examples/), но я до сих пор не понимаю, откуда взялась эта проблема. Хотелось бы узнать, в чем проблема и как ее исправить.

#include "pch.h"
#include <iostream>
#include "H5Cpp.h"

using namespace H5;

const H5std_string MEMBER1("name");
const H5std_string MEMBER2("nickname");

struct newStruct1 {
    char        name[4][10]{};
    char        nickname[4][10]{};
};


void struct_to_dataset(newStruct1 *ptr_struct)
{        
    H5File file("file.h5", H5F_ACC_TRUNC);

    hid_t dtype_str = H5Tcopy(H5T_C_S1);
    size_t size = 10 * sizeof(char);                    
    H5Tset_size(dtype_str, size);

    hsize_t dim[] = { 4 };   
    DataSpace space(1, dim);

    CompType mtype1(sizeof(newStruct1));
    mtype1.insertMember(MEMBER1, HOFFSET(newStruct1, name), dtype_str);
    mtype1.insertMember(MEMBER2, HOFFSET(newStruct1, nickname), dtype_str);

    DataSet dataset = file.createDataSet("dset", mtype1, space);

    dataset.write(ptr_struct, mtype1);  
}

int main()
{
    newStruct1 struct01;
    newStruct1 *ptr01 = &struct01;

    char word1[10] = { "hello" };
    char word2[10] = { "hey" };

    for (int i = 0; i < 4; i++) {
        std::copy(word1, word1 + 10, ptr01->name[i]);
        std::copy(word2, word2 + 10, ptr01->nickname[i]);
    }

    struct_to_dataset(ptr01);
}

person maynull    schedule 06.12.2019    source источник


Ответы (1)


Взгляните на HDFql, поскольку он может избавить вас от низкоуровневых деталей обработки составных наборов данных HDF5. Используя HDFql на C ++, вашу проблему можно решить следующим образом:

// define structure
struct data
{
    char name[10];
    char nickname[10];
};


// declare variables
char script[1024];
struct data values[4];
int i;


// create an HDF5 file named "file.h5"
HDFql::execute("CREATE FILE file.h5");


// use (i.e. open) HDF5 file "file.h5"
HDFql::execute("USE FILE file.h5");


// create a dataset named "dset" of data type compound of one dimension (size 4) composed of two members (name and nickname)
HDFql::execute("CREATE DATASET dset AS COMPOUND(name AS CHAR(10), nickname AS CHAR(10))(4)");


// populate variable "values"
for(i = 0; i < 4; i++)
{
    memcpy(values[i].name, "hello\0\0\0\0\0", 10);
    memcpy(values[i].nickname, "hey\0\0\0\0\0\0\0", 10);
}


// insert (i.e. write) values from variable "values" into dataset "dset"
sprintf(script, "INSERT INTO dset VALUES FROM MEMORY %d", HDFql::variableTransientRegister(values));
HDFql::execute(script);

Дополнительные сведения и примеры использования HDFql можно найти в справочном руководстве.

person SOG    schedule 09.05.2020