文件解析器出错 [英] File parser getting an error
本文介绍了文件解析器出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我尝试创建一个解析器来读取配置文件
错误显式专门化非命名空间'类转换'
我尝试了什么:
I am try in to create a parser with to read configuration files
error explicit specialisation in non namespace 'class Conversion'
What I have tried:
#include <iostream>
#include <string>
#include <sstream>
#include <map> //holding the pair of parameter-value
#include <fstream>
#include <stdlib.h>
#include <typeinfo>
void FileNotFound(const std::string &error)
{
std::cout << error;
std::cin.get();
exit(EXIT_FAILURE);
}
class Conversion
{
public:
template <typename T>
static std::string Ttostring(T const &val)
{
std::ostringstream ostr;
ostr << val;
return ostr.str();
}
template <typename T>
static T stringtoT(std::string const &val)
{
std::istringstream istr(val);
T returnVal;
if (!(istr >> returnVal))
FileNotFound("Not a valid " + (std::string)typeid(T).name() + " present\n");
return returnVal;
}
template <>
static std::string stringtoT(std::string const &val)
{
return val;
}
};
class Parser
{
private:
std::map<std::string, std::string> contents;
std::string filename;
//function itself is a const cannot call any non-const member functions, nor can it change any member variables.
void Deletecomments(std::string &line) const
{ //npos is a static member constant value with the greatest possible value for an element of type size_t
if (line.find(';') != line.npos)
line.erase(line.find(';'));
}
//Searches the string for the first character that does not match any of the characters specified in its arguments.
bool Whitespace(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 Key(std::string &key, size_t const &Pos, const std::string &line) const
{
key = line.substr(0, Pos);
if (key.find('\t') != line.npos || key.find(' ') != line.npos)
key.erase(key.find_first_of("\t "));
}
void Value(std::string &value, size_t const &Pos, const std::string &line) const
{
value = line.substr(Pos + 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 Pos = temp.find('=');
std::string key, value;
Key(key, Pos, temp);
Value(value, Pos, temp);
if (!keyExists(key))
contents.insert(std::pair<std::string, std::string>(key, value));
else
FileNotFound("Can only have unique key names!\n");
}
void parse(const std::string &line, size_t const lineNumber)
{
if (line.find('=') == line.npos)
FileNotFound("Cannot find separator " + Conversion::Ttostring(lineNumber) + "\n");
if (!validLine(line))
FileNotFound("Bad format for line: " + Conversion::Ttostring(lineNumber) + "\n");
extractContents(line);
}
/*
Extracting the parameter and values
*/
void getfield()
{
std::ifstream file;
file.open(filename.c_str()); //c_str() return the char*
if (!file)
FileNotFound("" + filename + " not found!\n");
std::string line;
size_t lineNumber = 0; //unsigned integer type
while (std::getline(file, line))
{
lineNumber++;
std::string temp = line;
if (temp.empty())
continue;
Deletecomments(temp);
if (Whitespace(temp))
continue;
parse(temp, lineNumber);
}
file.close();
}
public:
Parser(const std::string &filename)
{
this->filename = filename;
getfield();
}
bool keyExists(const std::string &key) const
{
return contents.find(key) != contents.end();
}
/*function that retrieves the value of a specific key
function returns a default value ValueType, if the key couldn't be found or,
it will return the Conversion value from string to ValueType
*/
template <typename ValueType>
ValueType getValueOfKey(const std::string &key, ValueType const &defaultValue = ValueType()) const
{
if (!keyExists(key))
return defaultValue;
return Conversion::stringtoT<ValueType>(contents.find(key)->second);
}
};
int main()
{
Parser Par("ParameterFile");
bool exists = Par.keyExists("Parameter1");
std::cout << "Parameter1 key: " << std::boolalpha << exists << "\n";
exists = Par.keyExists("Value1");
std::cout << "Value1 key: " << exists << "\n";
std::cin.get();
return 0;
}
推荐答案
以下是三种选择:
最简单的修复是摆脱Conversion类并编写getValueOfKey的专用版本。
备选2:使转换成为模板类(而不是带模板的类)成员)。
Here are three choices for you:
Easiest fix is to get rid of the Conversion class and write specialized versions of getValueOfKey.
Alternative 2: make Conversion a template class (instead of a class with template members).
template <typename T> class Conversion {
备选3:将转化设为命名空间。
Alternative 3: make Conversion a namespace.
<pre>namespace Conversion {
其他评论:
价值,关键,Whitespace,deleteComments和validLine可以是静态的而不是const成员函数。
Additional comments:
Value, Key, Whitespace, deleteComments, and validLine can be static instead of const member functions.
这篇关于文件解析器出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文