文件解析器出错 [英] File parser getting an error

查看:74
本文介绍了文件解析器出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试创建一个解析器来读取配置文件

错误显式专门化非命名空间'类转换'



我尝试了什么:



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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆