C/C ++ HDF5读取字符串属性 [英] C/C++ HDF5 Read string attribute

查看:235
本文介绍了C/C ++ HDF5读取字符串属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一位同事使用labview将ASCII字符串作为属性写入HDF5文件中.我可以看到该属性存在,并且可以读取,但是无法打印.

A colleague of mine used labview to write an ASCII string as an attribute in an HDF5 file. I can see that the attribute exist, and read it, but I can't print it.

该属性是,如HDF Viewer中所示:

The attribute is, as shown in HDF Viewer:

日期= 2015 \ 07 \ 09

Date = 2015\07\09

所以日期"是它的名字.

So "Date" is its name.

我正在尝试使用此代码读取属性

I'm trying to read the attribute with this code

hsize_t sz = H5Aget_storage_size(dateAttribHandler);
std::cout<<sz<<std::endl; //prints 16
hid_t atype = H5Aget_type(dateAttribHandler);
std::cout<<atype<<std::endl; //prints 50331867
std::cout<<H5Aread(dateAttribHandler,atype,(void*)date)<<std::endl; //prints 0
std::cout<<date<<std::endl; //prints messy characters!
//even with an std::string
std::string s(date);
std::cout<<s<<std::endl; //also prints a mess

为什么会这样?我如何以const char*std::string的形式获取此字符串?

Why is this happening? How can I get this string as a const char* or std::string?

我也尝试过使用类型atype = H5Tcopy (H5T_C_S1);,但这也不起作用...

I tried also using the type atype = H5Tcopy (H5T_C_S1);, and that didn't work too...

在这里,我根据要求提供了一个完整的,自包含的程序:

Here I provide a full, self-contained program as it was requested:

#include <string>
#include <iostream>
#include <fstream>
#include <hdf5/serial/hdf5.h>
#include <hdf5/serial/hdf5_hl.h>

std::size_t GetFileSize(const std::string &filename)
{
    std::ifstream file(filename.c_str(), std::ios::binary | std::ios::ate);
    return file.tellg();
}

int ReadBinFileToString(const std::string &filename, std::string &data)
{
    std::fstream fileObject(filename.c_str(),std::ios::in | std::ios::binary);
    if(!fileObject.good())
    {
        return 1;
    }
    size_t filesize = GetFileSize(filename);
    data.resize(filesize);
    fileObject.read(&data.front(),filesize);
    fileObject.close();
    return 0;
}

int main(int argc, char *argv[])
{
    std::string filename("../Example.hdf5");
    std::string fileData;
    std::cout<<"Success read file into memory: "<<
               ReadBinFileToString(filename.c_str(),fileData)<<std::endl;

    hid_t handle;
    hid_t magFieldsDSHandle;
    hid_t dateAttribHandler;
    htri_t dateAtribExists;

    handle = H5LTopen_file_image((void*)fileData.c_str(),fileData.size(),H5LT_FILE_IMAGE_DONT_COPY | H5LT_FILE_IMAGE_DONT_RELEASE);
    magFieldsDSHandle = H5Dopen(handle,"MagneticFields",H5P_DEFAULT);
    dateAtribExists = H5Aexists(magFieldsDSHandle,"Date");
    if(dateAtribExists)
    {
        dateAttribHandler = H5Aopen(magFieldsDSHandle,"Date",H5P_DEFAULT);
    }


    std::cout<<"Reading file done."<<std::endl;
    std::cout<<"Open handler: "<<handle<<std::endl;
    std::cout<<"DS handler: "<<magFieldsDSHandle<<std::endl;
    std::cout<<"Attributes exists: "<<dateAtribExists<<std::endl;
    hsize_t sz = H5Aget_storage_size(dateAttribHandler);
    std::cout<<sz<<std::endl;
    char* date = new char[sz+1];
    std::cout<<"mem bef: "<<date<<std::endl;
    hid_t atype = H5Aget_type(dateAttribHandler);
    std::cout<<atype<<std::endl;
    std::cout<<H5Aread(dateAttribHandler,atype,(void*)date)<<std::endl;
    fprintf(stderr, "Attribute string read was '%s'\n", date);
    date[sz] = '\0';
    std::string s(date);
    std::cout<<"mem aft: "<<date<<std::endl;
    std::cout<<s<<std::endl;

    H5Dclose(magFieldsDSHandle);
    H5Fclose(handle);


    return 0;
}

该程序的打印输出:

Success read file into memory: 0
Reading file done.
Open handler: 16777216
DS handler: 83886080
Attributes exists: 1
16
mem bef: 
50331867
0
Attribute string read was '�P7'
mem aft: �P7
�P7
Press <RETURN> to close this window...

谢谢.

推荐答案

原来,必须使用char指针的引用来调用H5Aread……所以指针的指针:

It turned out that H5Aread has to be called with a reference of the char pointer... so pointer of a pointer:

H5Aread(dateAttribHandler,atype,&date);

请记住,不必为此保留内存.该库将保留内存,然后您可以使用H5free_memory(date)释放它.

Keep in mind that one doesn't have to reserve memory for that. The library will reserve memory, and then you can free it with H5free_memory(date).

这很好.

我了解到只有当要读取的字符串具有可变长度时才是这种情况.如果字符串的长度固定,则必须手动保留大小为length+1的内存,甚至手动将最后一个字符设置为null(以获取以null结尾的字符串.hdf5库中有一个函数可以检查是否字符串的长度是固定的.

I learned that this is the case only when the string to be read has variable length. If the string has a fixed length, then one has to manually reserve memory with size length+1 and even manually set the last char to null (to get a null-terminated string. There is a function in the hdf5 library that checks whether a string is fixed in length.

这篇关于C/C ++ HDF5读取字符串属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆