2013-08-01 5 views
1

내가 가지고있는 샘플 코드에 몇 가지 문제가 있습니다. 이상적으로는 키워드와 관련된 데이터 (int 및 strings)가 변경 될 수있는 파일이 필요합니다. 언제든지 편집 할 수있는 기간 (int), 대상 (문자열) 및 소스 (소스)를 갖습니다. 이는 궁극적으로 파일을 원하는 시점과 위치, 시간대에 백업하는 데 사용하기 쉽습니다.구성 파일 구문 분석 중 오류가 발생했습니다.

이것은 샘플 코드이며, 몇 가지 오류를 해결했지만 마지막 몇 개에 붙어 있습니다. 아니면 이것에 대해 더 쉬운 방법이 있습니까? 죄송합니다 모두 뒤죽박죽, 나는 아주 새로운 C++입니다 ...

고맙습니다. 도움을 가져 주셔서 감사합니다. 어쩌면 누군가가 쉽게 읽을 수있는 쉬운 구성 파일 구문 분석에 대한 좋은 자습서가 있습니까?

내 GCC 버전 4.4.7

입니다 내가 잡 오전 오류는 다음과 같습니다

g ++ configFile.cpp configFile.cpp : 36 : 오류 : 비 네임 스페이스 범위 '클래스 변환'에서 명시 적으로 전문화 configFile.cpp : 정적 멤버 함수 'static T Convert :: string_to_T (const std :: string &)': configFile.cpp : 31 : 오류 : 템플릿 매개 변수에 의존하는 'exitWithError'에 대한 인수가 없습니다. 그래서 'exitWithError'선언을 사용할 수 있어야합니다. configFile.cpp : 31 : note : (' '-fpermissive, G ++는 당신이 그것을 전문으로하려고했던, 다음 코드와

#include <iostream> 
#include <string> 
#include <sstream> 
#include <map> 
#include <fstream> 
#include <vector> 
#include <stdio.h> 
#include <stdlib.h> 

using namespace std; 

class Convert 
{ 

public: 
template <typename T> 
static std::string T_to_string(T const &val) 
{ 
    std::ostringstream ostr; 
    ostr << val; 

    return ostr.str(); 
} 

template <typename T> 
static T string_to_T(std::string const &val) 
{ 
    std::istringstream istr(val); 
    T returnVal; 

    if (!(istr >> returnVal)) 
     exitWithError("CFG: Not a valid " + (std::string)typeid(T).name() + " received!\n"); 

    return returnVal; 
} 

template <> 
static std::string string_to_T(std::string const &val) 
{ 

    return val; 
} 
}; 

void exitWithError(const std::string &error) 
{ 
std::cout << error; 
std::cin.ignore(); 
std::cin.get(); 

exit(EXIT_FAILURE); 
} 

class ConfigFile 
{ 

private: 
std::map<std::string, std::string> contents; 
std::string fName; 

void removeComment(std::string &line) const 
{ 
    if (line.find(';') != line.npos) 
     line.erase(line.find(';')); 
} 

bool onlyWhitespace(const std::string &line) const 
{ 
    return (line.find_first_not_of(' ') == line.npos); 
} 

bool validLine(const std::string &line) const 
{ 
    std::string temp = line; 
    temp.erase(0, temp.find_first_not_of("\t ")); 

    if (temp[0] == '=') 

     return false; 

    for (size_t i = temp.find('=') + 1; i < temp.length(); i++) 

        if (temp[i] != ' ') 

      return true; 

    return false; 
} 

void extractKey(std::string &key, size_t const &sepPos, const std::string &line) const 
{ 
    key = line.substr(0, sepPos); 
    if (key.find('\t') != line.npos || key.find(' ') != line.npos) 
     key.erase(key.find_first_of("\t ")); 
} 
void extractValue(std::string &value, size_t const &sepPos, const std::string &line) const 
{ 
    value = line.substr(sepPos + 1); 
    value.erase(0, value.find_first_not_of("\t ")); 
    value.erase(value.find_last_not_of("\t ") + 1); 
} 
void extractContents(const std::string &line) 
{ 
    std::string temp = line; 
    temp.erase(0, temp.find_first_not_of("\t ")); 
    size_t sepPos = temp.find('='); 
    std::string key, value; 
    extractKey(key, sepPos, temp); 
    extractValue(value, sepPos, temp); 

    if (!keyExists(key)) 
     contents.insert(std::pair<std::string, std::string>(key, value)); 
    else 
     exitWithError("CFG: Can only have unique key names!\n"); 
} 
void parseLine(const std::string &line, size_t const lineNo) 
{ 
    if (line.find('=') == line.npos) 
     exitWithError("CFG: Couldn't find separator on line: " + Convert::T_to_string(lineNo) + "\n"); 

    if (!validLine(line)) 
     exitWithError("CFG: Bad format for line: " + Convert::T_to_string(lineNo) + "\n"); 

    extractContents(line); 
} 
void ExtractKeys() 
{ 
    std::ifstream file; 
    file.open(fName.c_str()); 
    if (!file) 
     exitWithError("CFG: File " + fName + " couldn't be found!\n"); 

    std::string line; 
    size_t lineNo = 0; 
    while (std::getline(file, line)) 
    { 

     lineNo++; 
     std::string temp = line; 
     if (temp.empty()) 
      continue; 

     removeComment(temp); 
     if (onlyWhitespace(temp)) 
      continue; 

     parseLine(temp, lineNo); 
    } 
    file.close(); 
} 
public: 
ConfigFile(const std::string &fName) 
{ 
    this->fName = fName; 
    ExtractKeys(); 
} 
bool keyExists(const std::string &key) const 
{ 
    return contents.find(key) != contents.end(); 
} 
template <typename ValueType> 

ValueType getValueOfKey(const std::string &key, ValueType const &defaultValue = ValueType()) const 
{ 
    if (!keyExists(key)) 
     return defaultValue; 

    return Convert::string_to_T<ValueType>(contents.find(key)->second); 
} 
}; 

int main() 
{ 

ConfigFile cfg("config.cfg"); 



bool exists = cfg.keyExists("car"); 

std::cout << "car key: " << std::boolalpha << exists << "\n"; 

exists = cfg.keyExists("fruits"); 

std::cout << "fruits key: " << exists << "\n"; 



std::string someValue = cfg.getValueOfKey<std::string>("mykey", "Unknown"); 

std::cout << "value of key mykey: " << someValue << "\n"; 

std::string carValue = cfg.getValueOfKey<std::string>("car"); 

std::cout << "value of key car: " << carValue << "\n"; 

double doubleVal = cfg.getValueOfKey<double>("double"); 

std::cout << "value of key double: " << doubleVal << "\n\n"; 



std::cin.get(); 

return 0; 

} 

답변

0

) 코드를 허용하지만 선언되지 않은 이름의 사용은 지원되지 않습니다 허용? 그런 경우 오류가 말한대로

template <> 
static std::string string_to_T(std::string const &val) 
{ 

    return val; 
} 

는 명시 적으로 전문화 클래스의 외부에서 정의되어야한다 (explicit specialization in non-namespace scope)가 필요합니다 : 당신이 Convert 또는 그것을 사용하기 전에 또한

template <> 
std::string Convert::string_to_T<std::string>(std::string const &val) 
{ 

    return val; 
} 

, 당신은 exitWithError 필요 컴파일러가 Convert에서 사용할 때 아직 보지 못했기 때문에 앞으로 선언하십시오. Convert의 정의 앞에 이동하십시오.

void exitWithError(const std::string &error) 
{ 
std::cout << error; 
std::cin.ignore(); 
std::cin.get(); 

exit(EXIT_FAILURE); 
} 
// Or just forward declare void exitWithError(const std::string &); 

class Convert 
{ .... 
+0

"exitWithError"로 인해 배치 오류가 발생하여 주셔서 감사합니다. 전문화 된 오류 때문에 전문화 할 필요가 없습니다. Fom은 내 연구를 위해 내가하려는 일을 성취하는 좋은 방법처럼 보였습니다. 다른 옵션을 권장합니까? 명시 적 전문화에 대한 오류가 여전히 발생하지만 실수를 파악할 수있을 때보고합니다. 제시, 고마워. – user2630969

+0

@ user2630969 : 전문 분야는 갈 길이 멀어 보입니다. [다음은 나를 위해 컴파일 된 코드 예제입니다] (http://coliru.stacked-crooked.com/view?id=6a4810be9bc5b661781797df409dfc02-f674c1a6d04c632b71a62362c0ccfc51). –

+0

제시. 고마워, 제시. 내가하려고했던 것이 바로 이거 야. 좋은 분위기를 보내는 방법! – user2630969

관련 문제