I tried creating and updating a string attribute but h5dump prints only the first character, is it a dataspace definition problem ?
std::string filepath;
hid_t acpl = H5Pcreate(H5P_ATTRIBUTE_CREATE);
assert(acpl != H5I_INVALID_HID);
// use UTF-8 encoding for the attribute name
herr_t status = H5Pset_char_encoding(acpl, H5T_CSET_UTF8);
assert(status >= 0);
// create a scalar (singleton) attribute
hid_t fspace = H5Screate(H5S_SCALAR);
assert(fspace != H5I_INVALID_HID);
hid_t attr = H5Acreate2(file, "filepath", H5T_C_S1, fspace, acpl,
H5P_DEFAULT);
assert(attr != H5I_INVALID_HID);
// update the attribute value
char testbuff[] = "Hello world";
status = H5Awrite(attr, H5T_C_S1, testbuff);
assert(status >= 0);
h5dump first couple of lines
HDF5 "squab.h5" {
GROUP "/" {
ATTRIBUTE "filepath" {
DATATYPE H5T_STRING {
STRSIZE 1;
STRPAD H5T_STR_NULLTERM;
CSET H5T_CSET_ASCII;
CTYPE H5T_C_S1;
}
DATASPACE SCALAR
DATA {
(0): "H"
}
}
GROUP "PolyMesh" {
contact
November 27, 2022, 8:48am
3
Hi @yue.nicholas ,
I believe variable testbuff
needs to be a pointer of a pointer for its content to be written properly into the attribute. In addition, you should set the size type as variable - something similar to H5Tset_size(type, H5T_VARIABLE);
.
Alternatively, you may want to give HDFql a try as it alleviates the user from HDF5 low-level details. To write a string into an attribute using HDFql in C++ could be done as follows:
// create an HDF5 file named 'squab.h5' and use (i.e. open) it
HDFql::execute("CREATE AND USE FILE squab.h5");
// create an attribute named 'filepath' and write string 'Hello world' into it
HDFql::execute("CREATE ATTRIBUTE filepath AS UTF8 VARCHAR VALUES(\"Hello world\")");
Hope it helps!
2 Likes
@contact Thanks for the tip.
I have rework the code, the following works for me
std::string filepath;
hid_t acpl = H5Pcreate(H5P_ATTRIBUTE_CREATE);
assert(acpl != H5I_INVALID_HID);
// use UTF-8 encoding for the attribute name
herr_t status = H5Pset_char_encoding(acpl, H5T_CSET_UTF8);
assert(status >= 0);
const char* testbuff[1] = {"Hello world"};
// create a scalar (singleton) attribute
hid_t fspace = H5Screate(H5S_SCALAR);
assert(fspace != H5I_INVALID_HID);
// create a variable length string type
hid_t attr_type = H5Tcopy(H5T_C_S1);
status = H5Tset_size(attr_type, H5T_VARIABLE);
assert(status >= 0);
hid_t attr = H5Acreate2(file, "filepath", attr_type, fspace, acpl,H5P_DEFAULT);
assert(attr != H5I_INVALID_HID);
// update the attribute value
status = H5Awrite(attr, attr_type, &testbuff);
assert(status >= 0);
H5Sclose(fspace);
H5Aclose(attr);
1 Like
gheber
November 28, 2022, 2:15pm
5
Glad you’ve figured it out, @yue.nicholas . For completeness:
H5T_C_S1
is shorthand for
DATATYPE H5T_STRING {
STRSIZE 1;
STRPAD H5T_STR_NULLTERM;
CSET H5T_CSET_ASCII;
CTYPE H5T_C_S1;
}
If you prefer a fixed-(byte-)length string, you could also use
status = H5Tset_size(attr_type, 11);
This should yield
DATATYPE H5T_STRING {
STRSIZE 11;
STRPAD H5T_STR_NULLTERM;
CSET H5T_CSET_ASCII;
CTYPE H5T_C_S1;
}
DATASPACE SCALAR
DATA {
(0): "Hello World"
}
G.
2 Likes