这是我的第一个问题:
我正在尝试从NetCDF文件中读取“全局属性”(使用C ++遗留API)。 “全局属性”是指添加到NcFile的属性,而不是NcVar。
对于大多数事情,“Example netCDF programs”很有用 - 但“全局属性”没有示例。
咨询“netcdfcpp.h”我发现了一些事情:
NcAtt* get_att(NcToken) const;
friend class NcFile;
NcAtt( NcFile*, NcToken);
NcValues* values( void ) const;
ncvalues.h
标题我的编码技巧不足以理解我如何在NcFile中的NcAtt类中返回存储为NcValue的字符串/ int / float。
附件是我的问题“NetCDF_test.cpp”的示例代码,“LoadNetCDF”函数的实现中缺少关键部分。
代码编译正常:(编辑:同样,“TestFile.nc”正确创建)
g++ -c NetCDF_test.cpp -o NetCDF_test.o
g++ -o NCTEST NetCDF_test.o -lnetcdf_c++ -lnetcdf
示例代码:
#include <iostream> // provides screen output (i.e. std::cout<<)
#include <netcdfcpp.h>
struct MyStructure {
std::string MyString;
int MyInt;
float MyFloat;
MyStructure(); // default constructor
int SaveNetCDF(std::string); // Save the struct content to "global attributes" in NetCDF
int LoadNetCDF(std::string); // Load the struct content from "global attributes" in NetCDF
};
MyStructure::MyStructure(void)
{
MyString = "TestString";
MyInt = 123;
MyFloat = 1.23;
}
int MyStructure::SaveNetCDF(std::string OUTPUT_FILENAME)
{
NcError err(NcError::silent_nonfatal);
static const int NC_ERR = 2;
NcFile NetCDF_File(OUTPUT_FILENAME.c_str(), NcFile::Replace);
if(!NetCDF_File.is_valid()) {return NC_ERR;}
if(!(NetCDF_File.add_att("MyString",MyString.c_str()))) {return NC_ERR;}
if(!(NetCDF_File.add_att("MyInt",MyInt))) {return NC_ERR;}
if(!(NetCDF_File.add_att("MyFloat",MyFloat))) {return NC_ERR;}
return 0;
}
int MyStructure::LoadNetCDF(std::string INPUT_FILENAME)
{
NcError err(NcError::silent_nonfatal);
static const int NC_ERR = 2;
NcFile NetCDF_File(INPUT_FILENAME.c_str(), NcFile::ReadOnly);
if(!NetCDF_File.is_valid()) {return NC_ERR;}
// ???? This is where I am stuck.
// How do I read the global attribute from the NetCDF_File ??
return 0;
}
int main()
{
std::cout<< "START OF TEST.\n";
MyStructure StructureInstance; // datamembers initialized by constructor
StructureInstance.SaveNetCDF("TestFile.nc");
StructureInstance.MyString = "Change string for sake of testing";
StructureInstance.MyInt = -987;
StructureInstance.MyFloat = -9.87;
StructureInstance.LoadNetCDF("TestFile.nc"); // data members are supposed to be read from file
std::cout<< "Now the data members of StructureInstance should be TestString, 123, and 1.23\n";
std::cout<< StructureInstance.MyString << " ; " << StructureInstance.MyInt << " ; " << StructureInstance.MyFloat <<"\n";
std::cout<< "END OF TEST.\n";
}
答案 0 :(得分:1)
在C ++用户指南中非常清楚地说明了这一点:http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx/Class-NcAtt.html#Class-NcAtt
&#34;因为属性仅与打开的netCDF文件相关联,所以此类没有公共构造函数。使用NcFile和NcVar的成员函数来获取netCDF属性或添加新属性。&#34;
全局属性是文件的属性(与变量属性相反,而变量属性是变量的属性)
NetCDF_File.num_atts()返回多少个全局属性。 get_att()方法(以各种方式重载)将为您提供属性。
咨询http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx/Class-NcFile.html#Class-NcFile
答案 1 :(得分:1)
非常感谢Rob Latham提供了对NetCDF API(旧版C ++)的注释描述的链接。根据那里给出的信息,我能够弄清楚:
NcAtt
inherents形成NcTypedComponent
一组成员函数,用于访问存储在给定NcAtt
内的数据:(int n == n-th element)
ncbyte as_ncbyte( int n ) const
char as_char( int n ) const
short as_short( int n ) const
int as_int( int n ) const
nclong as_nclong( int n ) const // deprecated
long as_long( int n ) const
float as_float( int n ) const
double as_double( int n ) const
char* as_string( int n ) const
但是,NcAtt的构造函数是私有的,现有NcAtt的唯一访问点是通过NcFile成员函数NcVar* get_var(NcToken name) const
- 它只返回一个指针。因此,直接使用不起作用:
int MyInt = MyNcFile.get_att("MyInt").as_int(0); // DOES NOT COMPILE
然而,取消引用get_att
返回的指针就可以了。
int MyInt = (*MyNcFile.get_att("MyInt")).as_int(0); // WORKS
为了完整起见,我在MyStructure::LoadNetCDF
的实现中包含了原始问题的示例代码。
int MyStructure::LoadNetCDF(std::string INPUT_FILENAME)
{
NcError err(NcError::silent_nonfatal);
static const int NC_ERR = 2;
NcFile NetCDF_File(INPUT_FILENAME.c_str(), NcFile::ReadOnly);
if(!NetCDF_File.is_valid()) {return NC_ERR;}
// NcAtt constructor is private, but one can obtain the pointer to an existing NcAtt
NcAtt* PointerToMyIntNcAtt = NetCDF_File.get_att("MyInt");
// Now, using the dereferencing operator one has access to the member functions that NcAtt inherents from NcTypedComponent
if(!(*PointerToMyIntNcAtt).is_valid()) {return NC_ERR;}
std::cout<< "Is MyInt a valid NcAtt? "<< (*PointerToMyIntNcAtt).is_valid()<<"\n";
// The concise way of writing the access to NetCDF "global attributes"" of type int/float/string
MyInt = (*NetCDF_File.get_att("MyInt")).as_int(0);
MyFloat = (*NetCDF_File.get_att("MyFloat")).as_float(0);
MyString = (*NetCDF_File.get_att("MyString")).as_string(0);
return 0;
}