C/C++ HDF5 读取字符串属性

2024-02-29

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

该属性如 HDF Viewer 中所示:

日期 = 2015\07\09

所以“日期”就是它的名字。

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

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* or std::string?

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

编辑: 在这里,我根据要求提供了一个完整的、独立的程序:

#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...

Thanks.


事实证明H5Aread必须使用 char 指针的引用来调用...所以指针的指针:

H5Aread(dateAttribHandler,atype,&date);

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

这很好用。

EDIT:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C/C++ HDF5 读取字符串属性 的相关文章

  • 在 WCF 上重用我的 PagedList 对象

    问题 我有一个自定义集合PagedList
  • 更新 Azure Blob 上的 LastModified

    我正在移植代码以使用 C 中的 Azure 存储 SDK 传统上 我称其为更新修改文件的上次写入 修改时间 File SetLastWriteTimeUtc fileName lastWriteTimeUtc 要更新 blob 的上次修改时
  • strtok() 使用安全吗[重复]

    这个问题在这里已经有答案了 我读到了很多负面的东西strtok 有人说它已经过时 有人说它不是线程安全的 等等 那么真相是什么 我可以使用吗strtok 它是线程安全的吗 Note 我正在使用 Visual C 您可以使用它 它是标准库的一
  • 如何通过覆盖 MSBuild 目标来防止外语资源生成?

    我正在致力于减少大型 C ASP NET 解决方案的编译时间 我们的解决方案使用通常的 resx 文件方法翻译成大约十几种外语 这些资源文件的解析和编译极大地减慢了我们的编译时间 并且是日常的挫败感 我知道可以创建自定义资源提供程序并摆脱
  • C# 异步任务比同步慢

    你知道为什么同步斐波那契方法比异步 等待更快并且比异步任务更快吗 我在每个项目方法上都使用了异步 所以主要是这是一个非常糟糕的方法 Code static int FibonacciSync int number if number 0 r
  • C# 中 PKCS11Interop 库的线程安全使用 [已关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在使用 PKCS11Interop 在 HSM 内执行密钥管理操作 我使用的 HSM 是 Thales PCI Express 下面是
  • 我可以将 char 或 DateTime 设置为 null 吗?

    我可以将 null 设置为char数据类型 并且DateTime在 C 中 多谢你们 这是不可能的 它是一个值类型 使用 char myChar null DateTime myDate null 这相当于 Nullable
  • 如何从不同的线程访问控件?

    如何从创建控件的线程以外的线程访问控件 避免跨线程错误 这是我的示例代码 private void Form1 Load object sender EventArgs e Thread t new Thread foo t Start p
  • 无法将参数从 `const char *` 转换为 `char *`

    鉴于此代码 void group build int size std string ips Build the LL after receiving the member list from bootstrap head new memb
  • 从内存流播放视频文件

    只是好奇看看这是否可能 我有一个 Windows 应用程序 它从我的电脑上的 avi 文件读取所有字节 然后将其存储在 byte 中 现在我的内存中有 avi 文件 我想直接从内存将其加载到某种视频播放器控件中 我尝试过使用 wmplaye
  • QSpinBox 输入 NaN 作为有效值

    我正在尝试扩展 QSpinBox 以能够输入 NaN 或 nan 作为有效值 根据文档 我应该使用 textFromValue valueFromText 和 validate 函数来完成此操作 但我无法让它工作 因为它仍然不允许我输入除数
  • 如何使用 CUDA/Thrust 对两个数组/向量根据其中一个数组中的值进行排序

    这是一个关于编程的概念问题 总而言之 我有两个数组 向量 我需要对一个数组 向量进行排序 并将更改传播到另一个数组 向量中 这样 如果我对 arrayOne 进行排序 则对于排序中的每个交换 arrayTwo 也会发生同样的情况 现在 我知
  • 如何在 Visual Basic DLL 和 C++ DLL 之间创建隔离/免注册 COM?

    我必须在 C DLL 中使用 VB COM DLL 我弄清楚了如何从 C DLL 访问 VB COM DLL 并且它可以工作 现在我遇到了一个问题 我必须使用隔离的 COM 免注册 COM 因为我无法在必须使用它的每台 PC 上注册 DLL
  • 原子存储抛出错误

    我最近升级到了 C 11 兼容编译器 并且尝试将一些代码从 boost 更新到 c 11 标准 我在使用atomic store转换一些代码时遇到了问题 这是一些简单的测试代码 似乎会引发编译器错误 int main std shared
  • asp.net core http 如果没有内容类型标头,则删除 `FromBody` 忽略

    我在 http 中使用 bodyDELETE要求 我知道目前删除主体是非标准的 但是允许的 使用时出现问题HttpClient它不允许删除请求的正文 我知道我可以使用SendAsync 但我宁愿让我的 API 更加灵活 我希望这个机构是可选
  • 展开 std::reference_wrapper 的成本

    Given include
  • 为什么 C++ 标准没有将 sizeof(bool) 定义为 1?

    Size of char signed char and unsigned char由 C 标准本身定义为 1 个字节 我想知道为什么它没有定义sizeof bool also C 03 标准 5 3 3 1 说 sizeof char s
  • 使用C标准数学库精确计算标准正态分布的CDF

    标准 C 数学库不提供计算标准正态分布 CDF 的函数 normcdf 然而 它确实提供了密切相关的函数 误差函数 erf 和互补误差函数 erfc 计算 CDF 的最快方法通常是通过误差函数 使用预定义常量 M SQRT1 2 来表示 d
  • C# PasswordDeriveBytes:似乎 Salt 并不重要

    可能我误解了什么 以下代码通过 CryptDeriveKey 使用两种不同的盐生成两个相等的密钥 这是控制台结果 盐1 21 3e 18 a3 9a 8b 5f gt 键 da 89 ea 3d 91 08 20 98 20 e9 dc 4
  • 如何通过API退出Win32应用程序?

    我有一个使用 Win32 API 编写的 C Win32 应用程序 我希望强制它在其中一个函数中退出 有没有类似的东西Exit or Destroy or Abort 类似的东西会终止它吗 哎呀呀呀呀呀呀 不要做任何这些事情 exit 和

随机推荐