내가 가지고있는 샘플 코드에 몇 가지 문제가 있습니다. 이상적으로는 키워드와 관련된 데이터 (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;
}
"exitWithError"로 인해 배치 오류가 발생하여 주셔서 감사합니다. 전문화 된 오류 때문에 전문화 할 필요가 없습니다. Fom은 내 연구를 위해 내가하려는 일을 성취하는 좋은 방법처럼 보였습니다. 다른 옵션을 권장합니까? 명시 적 전문화에 대한 오류가 여전히 발생하지만 실수를 파악할 수있을 때보고합니다. 제시, 고마워. – user2630969
@ user2630969 : 전문 분야는 갈 길이 멀어 보입니다. [다음은 나를 위해 컴파일 된 코드 예제입니다] (http://coliru.stacked-crooked.com/view?id=6a4810be9bc5b661781797df409dfc02-f674c1a6d04c632b71a62362c0ccfc51). –
제시. 고마워, 제시. 내가하려고했던 것이 바로 이거 야. 좋은 분위기를 보내는 방법! – user2630969