How to read NetCDF "global attribute" in C++ - c++

This is my first question:
I am trying to read "global attributes" from a NetCDF file (using the C++ legacy API). By "global attribute" I mean an attribute that was added to a NcFile, not to a NcVar.
For most things the "Example netCDF programs" are useful -- but there is no example for "global attributes".
Consulting the "netcdfcpp.h" I find a few things:
NcFile has a member function: NcAtt* get_att(NcToken) const;
NcAtt has NO public constructor
NcAtt is friends with NcFile: friend class NcFile;
NcAtt has a private constructor: NcAtt( NcFile*, NcToken);
NcAtt has a public member function NcValues* values( void ) const;
NcValues has an API defined through the ncvalues.h header
My coding skills are insufficient to understand how I get back at the string/int/float stored as NcValue, in an NcAtt class within NcFile.
Attached is a example code of my problem "NetCDF_test.cpp", with the critical part missing from the implementation of the "LoadNetCDF" function.
The code compiles OK with: (edit: also, "TestFile.nc" is created correctly)
g++ -c NetCDF_test.cpp -o NetCDF_test.o
g++ -o NCTEST NetCDF_test.o -lnetcdf_c++ -lnetcdf
Example code:
#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";
}

It's pretty clearly spelled out in the C++ users guide: http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx/Class-NcAtt.html#Class-NcAtt
"Because attributes are only associated with open netCDF files, there are no public constructors for this class. Use member functions of NcFile and NcVar to get netCDF attributes or add new attributes."
global attributes are attributes on the file (as opposed to variable attributes which are, well, attributes on the variable)
NetCDF_File.num_atts() returns how many global attributes. The get_att() methods (overloaded in various ways) will get you an attribute.
consult http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx/Class-NcFile.html#Class-NcFile

Many thanks to Rob Latham for the links to a commented description of the NetCDF API (legacy C++). With the information given there I was able to figure it out:
NcAtt inherents form NcTypedComponent a set of member functions for accessing data stored within a given 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
But still, the constructor for NcAtt is private and the only access point to an existing NcAtt is through the NcFile member function NcVar* get_var(NcToken name) const -- which only returns a pointer. Hence the straight forward usage does not work:
int MyInt = MyNcFile.get_att("MyInt").as_int(0); // DOES NOT COMPILE
However, dereferencing the pointer returned by get_att does the trick.
int MyInt = (*MyNcFile.get_att("MyInt")).as_int(0); // WORKS
For sake of completeness I include below the implementation of MyStructure::LoadNetCDF for the example code of my original question.
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;
}

Related

Set const int member variable outside the class (C++)

Let's say this is in Foo.h:
class Foo {
private:
const int MAXIMUM;
}
How do I initialize MAXIMUM to a certain value (100 in this case) in the Foo.cpp file? I tried
Foo::Foo() {
MAXIMUM = 100;
}
and got the error "expression must be a modifiable lvalue". Then I tried
const int Foo::MAXIMUM = 100;
and got the error "a nonstatic data member may not be defined outside its class". And that basically answers my question as "it's just not possible" but that just means my university messed up on the header file. So, is this possible or not?
Note: This is a university assignment, so I can't change the header file. I assume the logical solution would be to set MAXIMUM to 100 in the header file.
You can initialise const variables in two ways
In line initialisation
class Foo {
private:
const int MAXIMUM = 100;
};
Using initialisation list
class Foo {
Foo()
: MAXIMUM(100) {
}
Foo(const int MAXIMUM)
: MAXIMUM(MAXIMUM) {
}
private:
const int MAXIMUM;
}
In the below statenter code hereement
Foo::Foo() {
MAXIMUM = 100;
}
MAXIMUM is already created and you are trying to modify its value, which is not allowed for const variables.
In the below statement
const int Foo::MAXIMUM = 100;
MAXIMUM is not a static variable, so it will be bind with an object. You cannot access MAXIMUM using class name.
You want an initializer list:
Foo::Foo() : MAXIMUM(100)
{
}
"Const" and "Reference" variables are need to be initialized before class object is created. In your case,
Foo::Foo() { // **End of this line, object is getting created.**
MAXIMUM = 100; // *This line, gets Error: "expression must be a modifiable lvalue"*
}
to avoid this, you must use "Initialization list" where the value is assigned to variable before class constructor creates object.
Fix:
Foo::Foo():MAXIMUM(100) { // const variable is initialized
MAXIMUM = 200;
}

Header file refresh/update

I'm having some trouble using header files.
I would like to "refresh" a .h file, in order to update all the values of the constants in it which depend on an extern variable (defined in the main .cc file).
This is approximately the situation:
Header file (header.h)
extern int extern_value;
const int one = value;
const int two = value * 2;
const int three = value * 3;
Main program
#include "header.h"
int extern_value;
int main(){
extern_value = 10;
// Here is where I would like to refresh the header file.
// Here is where I would like to have my dependant constants
// (one, two and three) being updated.
return 0;
}
Please consider that this is an extreme approximation of the problem.
Do you guys have any idea about how to solve it?
Thanks in advance.
EDIT:
This is my actual problem:
I would like to have a header file which contains all the graphical constants that my project needs. They ALL depend on the size of the display. The first thing that the main program does is getting information about the display size; THEN, I would like the program to "export" this information on the header file, so it can calculate all the graphical constants relatively to the size of the display.
You can't do this. For a variety of reasons, but not least because your variables are const, and the expression you use to compute a value to be assigned to them is not continually re-evaluated.
What you want is to use functions:
extern int extern_value;
int one() { return extern_value; }
int two() { return extern_value * 2; }
int three() { return extern_value * 3; }
Other notes:
You probably shouldn't have an extern variable for this. Pass value to the function instead:
int one(const int value) { return value; }
int two(const int value) { return 2 * value; }
int three(const int value) { return 3 * value; }
int main() {
int value = 10;
std::cout << one(value) << " " << two(value) << "\n";
return 0;
}
You can't "refresh" a header file. The content of the file is what you typed, and this is included (effectively, pasted into) the source file when you use #include "my_header.h". You can update the value associated with non-const variables, but if you want to repeatedly evaluate an expression with different values, the best way is to turn that expression into a function as shown above, and call the function with different parameters.
You'll probably need to either move the function definitions from the header to a source file, or mark them as inline, otherwise you may be warned (or receive errors) about multiple definitions if you use the same header in multiple source files.
To address your actual problem, if you need to expose information through extern variables, you'll need to make them non-const, and have your main() function initialise them, or do so during static initialisation. There are a number of issues to be aware of when doing this, so it's much safer to provide functions that compute the geometry accordingly, and base those computations on one or two function arguments, or a small number of extern variables that are statically initialised to something safe, then set appropriately once the information becomes available. Further details can be obtained by searching for e.g. static initialisation or extern variables.
In this case, you may wish to consider creating a class to hold your geometry and perform the relevant computations. A pointer to an instance of this class can be created as an extern variable, and initialised on program initialisation (i.e. statically). You can then provide the derived "constants" as member functions which calculate their result based on a small number of encapsulated values, which can be set / updated if necessary. You can even make it such that these are const, if you're careful.
See, for instance the example below (live demo):
// ******** HEADER FILE ********
class Geometry {
public:
Geometry(const int rows, const int cols)
: rows_(rows), cols_(cols) {}
int rows() const { return rows_; }
int cols() const { return cols_; }
int pixels() const { return rows_ * cols_; }
// whatever other "constants" you need, defined as functions
// containing expressions based on rows_ and cols_.
private:
// Make copy constructor & assignment operator private to prevent copying
Geometry(const Geometry&);
Geometry& operator=(const Geometry&);
// The data from which everything else is calculated
const int rows_;
const int cols_;
};
extern const Geometry* the_geometry;
// ******** SOURCE FILE ********
#include <iostream>
int main() {
const int rows = 80; // or however you get the number of rows
const int columns = 25; // or however you get the number of columns
the_geometry = new Geometry(rows, columns);
std::cout << the_geometry->pixels() << "\n";
return 0;
}
const Geometry* the_geometry = nullptr;

How can I access a class's member function via an array of pointers?

I have a pretty standard class with some public member functions and private variables.
My problem originally stems from not being able to dynamically name object instances of my class so I created an array of pointers of the class type:
static CShape* shapeDB[dbSize];
I have some prompts to get info for the fields to be passed to the constructor (this seems to work):
shapeDB[CShape::openSlot] = new CShape(iParam1,sParam1,sParam2);
openSlot increments properly so if I were to create another CShape object, it would have the next pointer pointing to it. This next bit of code doesn't work and crashes consistently:
cout << shapeDB[2]->getName() << " has a surface area of: " << shapeDB[2]->getSA() << shapeDB[2]->getUnits() << endl;
The array of pointers is declared globally outside of main and the get() functions are public within the class returning strings or integers. I'm not sure what I'm doing wrong but something relating to the pointer set up I'm sure. I'm writing this code to try and learn more about classes/pointers and have gotten seriously stumped as I can't find anyone else trying to do this.
I'm also curious as to what the CShape new instances get named..? if there is any other way to dynamically create object instances and track the names so as to be able to access them for member functions, I'm all ears.
I've tried all sorts of permutations of pointer referencing/de-referencing but most are unable to compile. I can post larger chunks or all of the code if anyone thinks that will help.
class CShape {
int dim[maxFaces];
int faces;
string units;
string type;
string name;
bool initialized;
int slot;
public:
static int openSlot;
CShape();
CShape(int, string, string); // faces, units, name
~CShape();
void initialize(void);
// external assist functions
int getA(void) {
return 0;
}
int getSA(void) {
int tempSA = 0;
// initialize if not
if(initialized == false) {
initialize();
}
// if initialized, calculate SA
if(initialized == true) {
for(int i = 0; i < faces; i++)
{
tempSA += dim[i];
}
return(tempSA);
}
return 0;
}
string getUnits(void) {
return(units);
}
string getName(void) {
return(name);
}
// friend functions
friend int printDetails(string);
};
// constructor with values
CShape::CShape(int f, string u, string n) {
initialized = false;
faces = f;
units = u;
name = n;
slot = openSlot;
openSlot++;
}
My guess is you use the CShape constructor to increment CShape::openSlot?
You're probably changing the value before it's read, thus the pointer is stored in a different location.
Try replacing openSlot with a fixed value to rule out this CShape::option.
-- code was added --
I'm pretty sure this is the problem, the constructor is executed before the asignment, which means the lhs. will be evaluated after CShape::openSlot is incremented.

Assigning default values to arguments passed by reference

I want to do something like this:
int displayAll(Message *m, string &lastIndex, int &NumPrinted = 0 );
It gives me error, cribbing about int to int&.
I tried this too:
int temp =0;
int displayAll(Message *m, string &lastIndex, int &NumPrinted = temp );
Still it gives following error:
error: ISO C++ forbids in-class initialization of non-const static member 'temp'
Even static int temp; gives error.
error: ISO C++ forbids in-class initialization of non-const static member 'temp'
The problem with the first line of code you mention is that you are trying to pass a reference to a temporary variable
class Foo {
int displayAll(Message *m, bool &moreElements, string &lastIndex, int &NumPrinted = 0 );
};
The second bit of code complains because you were trying to initialize a class member statically.
class Foo {
int temp =0;
int displayAll(Message *m, bool &moreElements, string &lastIndex, int &NumPrinted = temp );
};
(I am putting your code inside of a class declaration to be clear about what is happening).
An easy way out of your problem that does not introduce a static variable is explicit function overloading:
class Foo {
inline int displayAll(Message *m, bool &moreElements, string &lastIndex) {
int dummy = 0;
return displayAll(m, moreElements, lastIndex, dummy);
}
int displayAll(Message *m, bool &moreElements, string &lastIndex, int &NumPrinted);
};
There's a bit of boilerplate, but it achieves what you want.
Hope this helps.
EDIT: Some more clarification. The core of the problem stems from the fact that the function must take a reference to some memory that it can modify. If you pass it a temporary variable (temporary as in the C++ meaning of the term, not just the english language term ) (as in your first line of code), it's illegal C++, since you usually copy a temporary to a value before you use it as an argument to a function:
void bar( int someNum = 0 ); // think of this as creating a temporary rvalue 0
// and then copying it into the function for use.
// temporary rvalues arise in expressions like
int v = 5 + 5; // the result of 5 + 5 is stored in a temporary rvalue, and then
// copied into v (which is an lvalue in this case).
So we need something that is an "lvalue", either some global variable somewhere or a temporary local variable ( in the english language sense ) as I gave in my answer. I was about to write a solution using a static variable, but there is a large flaw- since the static variable will be shared by all instances of your class, it will start out 0 and then be different every time you call the method ( since it would have been edted by the previous call). Even worse, in the case of multiple threads, you would be reading/writing to the same place of memory from several processors, so the value will be complete garbage, and you ill rape your processor cores' caches as each write will invalidate the cache of every other core. It's ugly, please don't do it. :P
By using my first solution you make the temporary variable very local, without much impact on anything else.
You can't do this for a non-const reference unless you declare temp to be static: see this stackoverflow post.
I fpund this interesting way of achieving this too:
class demo {
public:
void displayAll(int &x, int y = 0 ) {
int *p;
if(y)
p = (int*)y;
if(p) *p = 10;
x = 4;
}
};
int main() {
int x=0, y=0;
demo *obj = new demo();
obj->displayAll((x);
//obj->temp(x,(int)&y);
cout << "\n x= " << x << " y " << y;
return 0;
}

Why do we use 'this->' and not 'this.' to access members?

I was looking at a library a person has made for FaceBook in C++. The header file is this:
#ifndef __FACEBOOK_H__
#define __FACEBOOK_H__
/**
* Facebook Class
* Joel Seligstein
* Last mod: Aug 22, 2006
*
* This is the beginnings of a facebook class set and REST client. Its not documented
* yet nor nearly complete. But this is a release to demonstrate its usefulness.
* Please email joel#seligstein.com with suggestions or additions.
*
* TODO: Create classes/parsers for each request type
* TODO: Linux URL launcher
*/
//uncomment to have verbose output turned on
//#define fb_debug 1
//define which platform you're compiling for
#define fb_windows 1
//#define fb_linux 1
#include <string>
#include <sstream>
#include <list>
using namespace std;
#ifdef fb_windows
#include <windows.h>
#endif
#include "curl/curl.h"
#include "xmlParser/xmlParser.h"
#include "md5.h"
class facebook
{
public:
//app/session vars
string api_key;
string secret;
string token;
string server;
string session_key;
string session_secret;
string uid;
bool has_session;
facebook( string my_key, string my_secret, string my_server );
bool authenticate( );
bool request( string method, list<string> params, string *res );
bool load_token( );
void launch_login( string url );
bool get_session( );
void clean_up( );
private:
//curl info
CURL *curl;
CURLcode res;
int call_id;
//internal functions
string get_signature( list<string> params );
static string md5( string str );
static string get_param_string( list<string> params, bool separate );
static size_t write_callback( void *ptr, size_t size, size_t nmemb, void *userp );
};
#endif //__FACEBOOK_H__
Then inside the cpp file, my question is regarding this, the below is the constructor:
facebook::facebook( string my_key, string my_secret, string my_server )
{
this->api_key = my_key;
this->secret = my_secret;
this->server = my_server;
this->has_session = false;
this->call_id = 0;
}
Why have they used the -> operator and not .?
I have a limited understanding that -> accesses properties and methods of the type directly in memory but I am confused, I would, through ignorance, expect to see:
facebook::facebook( string my_key, string my_secret, string my_server )
{
this.api_key = my_key;
this.secret = my_secret;
this.server = my_server;
this.has_session = false;
this.call_id = 0;
}
All I want to know is the theory behind why -> is used over the dot notation.
UPDATE:
For anyone else in the same boat as me and learning C++. I have expanded on an example posted by a member in this question. I have also wrapped in initialization list for a member field.
#include "stdafx.h"
#include <iostream>
using namespace std;
class A {
private:
int x;
public:
A() : x(0){}
int getX() const {return x;}
void setX(int xx) {x += xx;}
};
int main()
{
A a;
a.setX(13);
A *pa = &a;
pa->setX(2);
A b = a;
b.setX(5);
cout << "a" << a.getX() << endl;
cout << "a*" << pa->getX() << endl;
cout << "b" << b.getX() << endl;
return 0;
}
this is a pointer to the current object i.e., inside methods (or constructor) of class A, this is of type A *.
(Note that, if the method is tagged as const, this is of type A const *.)
Hence the use of -> (designed only for pointers) and not . (designed only for class objects A or references to class objects A&).
In C++, this is a pointer to the self object. It's a relic leftover from early versions of C++, before it had references. If this were added to the language now, it probably would be a reference, for which you'd use the . notation.
Because inside a class or struct member, "this" is a special pointer that points to the current instance.
Any time you're accessing members of a class or struct through a pointer, the -> operator is used.
If you're accessing them through anything that isn't a pointer (usually a reference), the dot operator is used instead.
It's worth noting that the this-> syntax isn't necessary except in some forms of template instanciation. A lot of people choose to use it for stylistic reasons, though. There are a couple questions related to rationale behind this on S.O. already.
You may consider the following example.
class A {
int x;
public:
int getX() const {return x;}
void setx(int xx) {x = xx;}
};
int main()
{
A a;
a.setX(13);
cout << a.getX() << endl;
A *pa = &a;
cout << pa->getX() << endl;
return 0;
}
Notice that, dot operator (.) is used when calling a member function of A directly with the object a. The arrow operator (->) is used when calling a member function of A indirectly through a pointer of type A (A *pa = &a).
In C++, this is a pointer to the invoking object. Thus we could also define A::getX() function as follows:
int getX() const {return this->x;}
Or:
int getX() const {return (*this).x;}
this is a pointer of object A, thus *this dereferences it. So we could use both of the functions above.
As said, this is a pointer and not a reference. Thus you need the -> operator that is roughly (while not exactly the same as): (*this).
They differ in that you can overload -> operator or * operator in a class and can have different semantics. As a matter of fact, if a class overrides operator-> and the returned value is not a raw pointer, the compiler will keep on applying operator-> to the returned object until it reaches a native pointer. Operator . cannot be overloaded.
In the constructor you pointed, the use of this is completely optional as there is no name collision the code could just have named the attributes without further qualification.
facebook::facebook( string my_key, string my_secret, string my_server )
{
api_key = my_key;
secret = my_secret;
server = my_server;
has_session = false;
call_id = 0;
}
And a better solution would be using an initialization list. If you are interested in learning C++ google for it.
because "this" is a special pointer that refers to the current object and we use "->" to access the members of the object through pointers and "." is used for calling the member of a object directly.