我正在编写代码来生成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
以下是代码段:
#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]);
}
}
以下是相关代码段的标准输出:
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
在这里有什么打击你的奇怪吗?
答案 0 :(得分: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个可变长度属性。