2015-01-16 2 views
1

이 내 첫 번째 질문입니다 읽는 방법 : I합니다 (C++ 레거시 API를 사용) netCDF의 파일에서 "전역 속성"을 읽으려고하고C에서 netCDF의 "전역 속성"++

합니다. "글로벌 속성"이란 NcVar가 아닌 NcFile에 추가 된 속성을 의미합니다.

대부분의 경우 "Example netCDF programs"이 유용하지만 "전역 속성"에 대한 예는 없습니다. friend class NcFile; : NcAtt* get_att(NcToken) const;

  • NcAtt이 NcFile와
  • NcAtt 친구 아니 public 생성자가 없습니다 :

    • NcFile이 멤버 함수를 가지고 다음은 "netcdfcpp.h"나는 몇 가지를 찾을 컨설팅

    • NcAtt에는 전용 생성자가 있습니다. NcAtt(NcFile*, NcToken);
    • NcAtt에는 공개 멤버 함수가 있습니다. NcValues* values(void) const;
    • NcValues는

    내 코딩 기술은 내가 NcFile 내 NcAtt 클래스에서 다시 NcValue로 저장 문자열/INT/플로트에서 얻을 방법을 이해하기에 충분하다 ncvalues.h 헤더를 통해 정의 된 API가 있습니다.

    "LoadNetCDF"기능의 구현에서 중요한 부분이 누락 된 "NetCDF_test.cpp"문제의 예제 코드가 첨부되어 있습니다. (편집 : 또한, "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"; 
    } 
    
  • 답변

    1

    많은 감사를 참조 NetCDF API (레거시 C++)(INT n 개의 == n 번째 요소)

      :

      NcAtt inherents 주어진 NcAtt 내에 저장된 데이터에 액세스 멤버 함수 세트 NcTypedComponent 형성 :이 소정의 정보로 I 알아낼 수 있었다

    • 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; 
    } 
    
    +0

    '(* NetCDF_File) .as_int (0)'을'NetCDF_File-> as_int (0)'으로 대체해서는 안됩니까? – DopplerShift

    +0

    이것은 NcVar와 관련된 속성을 읽는 방법입니다.하지만 연산자가 분명히 구현되지 않았으므로 "전역 속성"에서는 작동하지 않습니다. "->"연산자를 사용하여 컴파일 할 때 다음 오류가 발생합니다 :'error : '->'의 기본 피연산자가 포인터 타입이 아닌 'NcFile'' – Mathis

    +0

    Ooops, 그 :'NetCDF_File.get_att ("MyInt") -> as_int (0)'... 아니면 실패합니까? – DopplerShift

    1

    그것은 꽤입니다

    코드로 확인 컴파일 C++ 사용자 가이드에서 명확하게 설명합니다. http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx/Class-NcAtt.html#Class-NcAtt

    "속성은 열려있는 netCDF 파일과 만 연결되기 때문에이 클래스에 대한 공용 생성자가 없습니다. NcFile 및 NcVar의 사용 멤버 함수는 netCDF의 속성을 얻거나 새로운 속성을 추가 할 수 있습니다. "

    NetCDF_File을 (잘, 변수에 속성이있는 변수 속성 반대)

    글로벌 속성이 파일에 대한 속성입니다. num_atts()는 얼마나 많은 전역 속성은 반환한다. get_att() 메서드 (다양한 방법으로 과부하) 당신에게 속성을 얻을 것이다.

    가의 주석 설명에 링크 롭 레이 텀에 http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx/Class-NcFile.html#Class-NcFile