【问题标题】:HDF5 attributes: Strings are only one character longHDF5 属性:字符串只有一个字符长
【发布时间】:2014-07-04 09:18:52
【问题描述】:

我正在编写代码来生成 HDF,但我遇到了属性问题。这些属性都是可变长度字符串,从文本文件中读取,但我将它们的上限限制在 256 个字符。

我的代码编译并运行没有错误。当我在 HDFView 中打开文件时,所有属性都有正确的名称,但只显示字符串中的第一个字符。

我已经开始编写将属性作为单个字符串或字符串数​​组接受的代码。我还没有完成那部分,所以现在它对字符串数组没有任何作用。

这是输入文件:

year 2013
julian_date 23
start_time_utc 13:54:03
end_time_utc 14:32:05
pixels_per_degree 1000
latitude_corners 34.988644 35.503284 35.960529 36.364529
longitude_corners -119.571877 -118.467979 -120.158424 -119.004395

这里是sn-p的代码:

#define FIELDSTRINGLENGTH 256

/*...*/

while(fgets(line, ATTRSTRINGLENGTH, topattributefile)!=NULL) {
  //parse line into individual words                                                                                                                                         
  field=strtok(line," \n");
  strncpy(attributename, field, FIELDSTRINGLENGTH);
  numfields=0;
  field=strtok(NULL," \n");
  while(field!=NULL) {
    strncpy(attributevalue[numfields++], field, FIELDSTRINGLENGTH);
    field=strtok(NULL," \n");
  }
  if(numfields==0) {printf("ERROR: Attribute %s had no value; skipping\n", attributename);}
  else if(numfields>1) {
    if(verboseflag) {printf("Making array of %d attributes with name %s:\n",
                            numfields, attributename);}
    for(i=0;i<numfields;i++) {
      if(verboseflag) {printf("\t%d: %s\n", i, attributevalue[i]);}
    }
  }
  else {
    printf("Making single attribute: %s: %s\n",
                            attributename, attributevalue[0]);}
    //make single attribute                                                                                                                                                  
    attrdataspaceid = H5Screate(H5S_SCALAR);
    attrdatatypeid = H5Tcopy(H5T_C_S1);
    status = H5Tset_size(attrdatatypeid, FIELDSTRINGLENGTH);
    status = H5Tset_strpad(attrdatatypeid, H5T_STR_NULLTERM);
    attributeid = H5Acreate2(fileid, attributename, attrdatatypeid, attrdataspaceid, H5P_DEFAULT, H5P_DEFAULT);
    status = H5Awrite(attributeid, H5T_C_S1, attributevalue[0]);
  }
}

这里是相关sn-p的标准输出:

Making top level attributes...
Making single attribute: year: 2013
Making single attribute: julian_date: 23
Making single attribute: start_time_utc: 13:54:03
Making single attribute: end_time_utc: 14:32:05
Making single attribute: pixels_per_degree: 1000
Making array of 4 attributes with name latitude_corners:
    0: 34.988644
    1: 35.503284
    2: 35.960529
    3: 36.364529
Making array of 4 attributes with name longitude_corners:
    0: -119.571877
    1: -118.467979
    2: -120.158424
    3: -119.004395
Finished making top level attributes.

最后,这是在 HDFView 中读取的 HDF 元数据。

XXXX.XXXXXX.XXXXXX.hdf (0)
    Group size = 1
    Number of attributes = 5
        year = 2
        julian_date = 2
        start_time_utc = 1
        end_time_utc = 1
        pixels_per_degree = 1

这里有什么让你觉得奇怪的地方吗?

【问题讨论】:

  • 空间不是你要求的空间问题吗? attrdataspaceid = H5Screate(H5S_SCALAR); 我的意思是这条线。我认为它也应该是H5T_C_S1。不过不确定。

标签: c string hdf5


【解决方案1】:

您的错误在于您对H5Awrite() 的调用。

status = H5Awrite(attributeid, H5T_C_S1, attributevalue[0]);

这只是写一个字符。因为H5T_C_S1的定义是

一个字节、以空结尾的八位字符字符串。

我通常创建一个派生类型并设置它的大小。然后用这个类型调用H5Awrite,因为写调用会复制这个在内存类型中的大小。

这是一个简单的例子。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hdf5.h>

#define FILENAME "att_str.h5"

int main(){

        hid_t    fid;
        hid_t    att;
        hid_t    ds;
        hid_t    type;
        herr_t   status;
        char     x[] = "lah lah lah";
        int32_t  len = 0;

        fid     = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
        type    = H5Tcopy(H5T_C_S1);
        len     = strlen(x);
        status  = H5Tset_size(type, len);
        ds      = H5Screate(H5S_SCALAR);
        att     = H5Acreate(fid, "test", type, ds, H5P_DEFAULT, H5P_DEFAULT);
        status  = H5Awrite(att, type, &x);

        status  = H5Aclose(att);
        status  = H5Tclose(type);
        status  = H5Sclose(ds);
        status  = H5Fclose(fid);

        return(EXIT_SUCCESS);
}

一旦编译并运行,生成的文件包含:

HDF5 "att_str.h5" {
GROUP "/" {
   ATTRIBUTE "test" {
      DATATYPE  H5T_STRING {
         STRSIZE 11;
         STRPAD H5T_STR_NULLTERM;
         CSET H5T_CSET_ASCII;
         CTYPE H5T_C_S1;
      }
      DATASPACE  SCALAR
      DATA {
      (0): "lah lah lah"
      }
   }
}
}

注意我如何创建一个派生类型,它是要写入的字符串的长度:

len     = strlen(x);
status  = H5Tset_size(type, len);

HDF5 组确实有一个example 写入可变长度属性。

【讨论】:

    猜你喜欢
    • 2018-08-19
    • 2015-09-29
    • 1970-01-01
    • 2011-06-04
    • 2011-03-25
    • 1970-01-01
    • 2019-01-29
    • 2018-12-31
    • 2017-09-29
    相关资源
    最近更新 更多