c++参数管理

/*
 * ArgumentMan.h
 */
#pragma once
#include <map>
#include <vector>
#include <set>
#include <string>
#include <algorithm>
#include <assert.h>
#include <stdlib.h>

#ifdef _MSC_VER
#pragma  warning( push ) 
#pragma warning(disable:4996)
#endif

namespace AM
{
#define TEMPLATE template<class _Str/*=std::string*/, typename _Chr/*=char*/>

	//_Str = std::string || std::wstring, _Chr = char || wchar_t
	template<class _Str = std::string, typename _Chr = char>
	class CArgumentMan
	{
	public:
		CArgumentMan(void);
		virtual ~CArgumentMan(void);

	public:
		//添加命令标识符
		void AddCmdFlag(_Chr cCmdFlag);
		//设置是否多值 bValue==true:-key value1 value2
		void SetMultiValue(bool bValue);
		//设置是否参数标志忽略大小写
		void SetIgnoreCase(bool bValue);
		//解析命令行
		void Parse(int argc, _Chr **argv);
		//重置
		void Reset();

	public://没有参数名的参数值使用 ""(空字符串)作为key 去获取
		//获得参数
		const std::map<_Str, std::vector<_Str>> &GetArgs();
		std::vector<_Str> GetArgs(const _Str &sArgName);
		//获得参数(只获得一个参数)
		_Str GetArg(const _Str &sArgName);
		//判断是否有参数
		bool Has(std::vector<_Str> &vctOutArgs, const _Str &sArgName);
		bool Has(_Str &sOutArg, const _Str &sArgName);

		只能在_Str为std::wstring时可使用//
		//获得参数
		std::map<std::string, std::vector<std::string>> ToAnsiArgs();
		//获得参数
		std::vector<std::string> GetAnsiArgs(const std::string &sArgName);
		//获得参数(只获得一个参数)
		std::string GetAnsiArg(const std::string &sArgName);
		//判断是否有参数
		bool HasAnsi(std::string &sOutArg, const std::string &sArgName);
		bool HasAnsi(std::vector<std::string> &vctOutArgs, const std::string &sArgName);
		//
		只能在_Str为std::string 时可使用//
		//获得参数
		std::map<std::wstring, std::vector<std::wstring>> ToUnicodeArgs();
		//获得参数
		std::vector<std::wstring> GetUnicodeArgs(const std::wstring &sArgName);
		//获得参数(只获得一个参数)
		std::wstring GetUnicodeArg(const std::wstring &sArgName);
		//判断是否有参数
		bool HasUnicode(std::wstring &sOutArg, const std::wstring &sArgName);
		bool HasUnicode(std::vector<std::wstring> &vctOutArgs, const std::wstring &sArgName);
		//

	protected:
		template<class T>
		T& makeName(T& name);

	private:
		std::map<_Str, std::vector<_Str>> m_mapArgument;//命令集合
		std::set<_Chr> m_setCmdFlag;  //名字标志符
		bool m_bMultiValue; //一个参数标志后面是否允许多个值(例如:/F v1 v2 v3)
		bool m_bIgnoreCase; //忽略参数标志大小写
	};

	//

	//unicode 转为 ansi
	bool WideByte2Ansi(std::string &out, const wchar_t* wstrcode)
	{
#if 0
		int ansiSize = ::WideCharToMultiByte(CP_OEMCP, 0, wstrcode, -1, NULL, 0, NULL, NULL);
		if (ansiSize == ERROR_NO_UNICODE_TRANSLATION)
		{
			//throw std::exception("Invalid UTF-8 sequence.");
			return false;
		}
		if (ansiSize == 0)
		{
			//throw std::exception("Error in conversion.");
			return false;
		}

		out.resize(ansiSize, '\0');
		int convresult = ::WideCharToMultiByte(CP_OEMCP, 0, wstrcode, -1, const_cast<char *>(out.c_str()), ansiSize, NULL, NULL);
		if (convresult != ansiSize)
		{
			//throw std::exception("La falla!");
			return false;
		}
		out.resize(strlen(out.c_str()));
#else
		size_t nLen = wcslen(wstrcode) * 2;
		if (nLen == 0)
		{
			out.resize(0);
			return true;
		}

		setlocale(LC_ALL, "zh_CN");
		char* ar = new char[nLen + 1];
		memset(ar, 0, nLen + 1);
		size_t read = wcstombs(ar, wstrcode, nLen);
		out = ar;
		out.resize(read);
		delete[] ar;
		setlocale(LC_ALL, "");
#endif
		return true;
	}

	//ansi 转 Unicode
	bool Ansi2WideByte(std::wstring& out, const char* strAnsi)
	{
#if 0
		int widesize = ::MultiByteToWideChar(CP_ACP, 0, strAnsi, -1, NULL, 0);
		if (widesize == ERROR_NO_UNICODE_TRANSLATION)
		{
			//throw std::exception("Invalid UTF-8 sequence.");
			return false;
		}
		if (widesize == 0)
		{
			//throw std::exception("Error in conversion.");
			return false;
		}

		out.resize(widesize, '\0');
		int convresult = ::MultiByteToWideChar(CP_ACP, 0, strAnsi, -1, const_cast<wchar_t*>(out.c_str()), widesize);
		if (convresult != widesize)
		{
			//throw std::exception("La falla!");
			return false;
		}
		out.resize(wcslen(out.c_str()));
#else
		size_t nLen = strlen(strAnsi) * 2;
		if (nLen == 0)
		{
			out.resize(0);
			return true;
		}

		setlocale(LC_ALL, "zh_CN");
		wchar_t* ar = new wchar_t[nLen + 1];
		memset(ar, 0, nLen + 1);
		size_t read = mbstowcs(ar, strAnsi, nLen);
		out = ar;
		out.resize(read);
		delete[] ar;
		setlocale(LC_ALL, "");
#endif
		return true;
	}

	TEMPLATE
		CArgumentMan<_Str, _Chr>::CArgumentMan(void)
		: m_bMultiValue(false)
		, m_bIgnoreCase(false)
	{
	}

	TEMPLATE
		CArgumentMan<_Str, _Chr>::~CArgumentMan(void)
	{
	}

	TEMPLATE
		template<class T>
	T& AM::CArgumentMan<_Str, _Chr>::makeName(T& name)
	{
		if (m_bIgnoreCase)//是否区别大小写
		{
			transform(name.begin(), name.end(), name.begin(), towupper);//全部转换成大写
		}
		return name;
	}

	TEMPLATE
		void CArgumentMan<_Str, _Chr>::AddCmdFlag(_Chr cCmdFlag)
	{
		m_setCmdFlag.insert(cCmdFlag);
	}

	TEMPLATE
		void CArgumentMan<_Str, _Chr>::SetMultiValue(bool bValue)
	{
		m_bMultiValue = bValue;
	}

	TEMPLATE
		void CArgumentMan<_Str, _Chr>::SetIgnoreCase(bool bValue)
	{
		m_bIgnoreCase = bValue;
	}

	TEMPLATE
		void CArgumentMan<_Str, _Chr>::Parse(int argc, _Chr **argv)
	{
		std::set<_Chr>::iterator itSetEnd = m_setCmdFlag.end();
		std::map<_Str, std::vector<_Str>>::iterator itMapEnd = m_mapArgument.end();

		_Str sLocalCmd;
		for (int i = 0; i < argc; ++i)
		{
			_Str sCmd = argv[i];
			if (m_setCmdFlag.find(sCmd[0]) != itSetEnd)
			{//找到命令标志  
				sCmd.erase(sCmd.begin());
				makeName<_Str>(sCmd);

				std::map<_Str, std::vector<_Str>>::iterator itMapFinder = m_mapArgument.find(sCmd);
				if (itMapFinder == itMapEnd)
				{
					m_mapArgument.insert(std::make_pair(sCmd, std::vector<_Str>()));
				}

				sLocalCmd = sCmd;
			}
			else
			{
				std::map<_Str, std::vector<_Str>>::iterator itMapFinder = m_mapArgument.find(sLocalCmd);
				if (itMapFinder == itMapEnd)
				{
					m_mapArgument.insert(std::make_pair(sLocalCmd, std::vector<_Str>()));
					itMapFinder = m_mapArgument.find(sLocalCmd);
				}
				itMapFinder->second.push_back(sCmd);

				if (!m_bMultiValue)//是否多值
				{
					sLocalCmd.resize(0);
				}
			}
		}

	}

	TEMPLATE
		void CArgumentMan<_Str, _Chr>::Reset()
	{
		m_setCmdFlag.clear();
		m_mapArgument.clear();
	}

	TEMPLATE
		std::vector<_Str> CArgumentMan<_Str, _Chr>::GetArgs(const _Str &sArgName)
	{
		_Str sArgNameUpper = sArgName;
		makeName<_Str>(sArgNameUpper);

		std::map<_Str, std::vector<_Str>>::iterator itMapFinder
			= m_mapArgument.find(sArgNameUpper);
		if (itMapFinder != m_mapArgument.end())
		{
			return itMapFinder->second;
		}

		return std::vector<_Str>();
	}

	TEMPLATE
		const std::map<_Str, std::vector<_Str>> & CArgumentMan<_Str, _Chr>::GetArgs()
	{
		return m_mapArgument;
	}

	TEMPLATE
		_Str CArgumentMan<_Str, _Chr>::GetArg(const _Str &sArgName)
	{
		_Str sArgNameUpper = sArgName;
		makeName<_Str>(sArgNameUpper);

		std::map<_Str, std::vector<_Str>>::iterator itMapFinder
			= m_mapArgument.find(sArgNameUpper);
		if (itMapFinder != m_mapArgument.end())
		{
			return (itMapFinder->second).at(0);
		}

		return _Str();
	}

	TEMPLATE
		bool CArgumentMan<_Str, _Chr>::Has(std::vector<_Str> &vctOutArgs, const _Str &sArgName)
	{
		_Str sArgNameUpper = sArgName;
		makeName<_Str>(sArgNameUpper);

		std::map<_Str, std::vector<_Str>>::iterator itMapFinder
			= m_mapArgument.find(sArgNameUpper);
		if (itMapFinder != m_mapArgument.end())
		{
			vctOutArgs = itMapFinder->second;
			return true;
		}

		return false;
	}

	TEMPLATE
		bool CArgumentMan<_Str, _Chr>::Has(_Str &sOutArg, const _Str &sArgName)
	{
		_Str sArgNameUpper = sArgName;
		makeName<_Str>(sArgNameUpper);

		std::map<_Str, std::vector<_Str>>::iterator itMapFinder
			= m_mapArgument.find(sArgNameUpper);
		if (itMapFinder != m_mapArgument.end())
		{
			if (itMapFinder->second.empty())
			{
				sOutArg.resize(0);
			}
			else
			{
				sOutArg = itMapFinder->second.at(0);
			}
			return true;
		}

		return false;
	}

	TEMPLATE
		std::map<std::string, std::vector<std::string>> AM::CArgumentMan<_Str, _Chr>::ToAnsiArgs()
	{
		int nFromSize = sizeof(_Str().c_str()[0]);
		int nToSize = sizeof(std::string().c_str()[0]);
		assert(nFromSize > nToSize);

		std::map< std::string, std::vector<std::string> > ret;
		for (std::map< _Str, std::vector<_Str> >::iterator it = m_mapArgument.begin();
			it != m_mapArgument.end(); ++it)
		{
			std::string key; std::vector<std::string> args;
			WideByte2Ansi(key, it->first.c_str());

			std::vector<_Str>& _args = it->second;
			size_t nArgs = _args.size();
			for (size_t i = 0; i < nArgs; ++i)
			{
				std::string arg;
				WideByte2Ansi(arg, _args[i].c_str());
				args.push_back(arg);
			}

			ret.insert(std::make_pair(key, args));
		}

		return ret;
	}

	TEMPLATE
		std::map<std::wstring, std::vector<std::wstring>> AM::CArgumentMan<_Str, _Chr>::ToUnicodeArgs()
	{
		int nFromSize = sizeof(_Str().c_str()[0]);
		int nToSize = sizeof(std::wstring().c_str()[0]);
		assert(nFromSize < nToSize);

		std::map< std::wstring, std::vector<std::wstring> > ret;
		for (std::map< _Str, std::vector<_Str> >::iterator it = m_mapArgument.begin();
			it != m_mapArgument.end(); ++it)
		{
			std::wstring key; std::vector<std::wstring> args;
			Ansi2WideByte(key, it->first.c_str());

			std::vector<_Str>& _args = it->second;
			size_t nArgs = _args.size();
			for (size_t i = 0; i < nArgs; ++i)
			{
				std::wstring arg;
				Ansi2WideByte(arg, _args[i].c_str());
				args.push_back(arg);
			}

			ret.insert(std::make_pair(key, args));
		}

		return ret;
	}

	TEMPLATE
		std::vector<std::string> AM::CArgumentMan<_Str, _Chr>::GetAnsiArgs(const std::string &sArgName)
	{
		std::string name = sArgName;
		makeName<std::string>(name);

		std::map< std::string, std::vector<std::string> > argsMap = ToAnsiArgs();
		if (argsMap.find(name) != argsMap.end())
			return argsMap[name];
		return std::vector<std::string>();
	}

	TEMPLATE
		std::vector<std::wstring> AM::CArgumentMan<_Str, _Chr>::GetUnicodeArgs(const std::wstring &sArgName)
	{
		std::wstring name = sArgName;
		makeName<std::wstring>(name);

		std::map< std::wstring, std::vector<std::wstring> > argsMap = ToUnicodeArgs();
		if (argsMap.find(name) != argsMap.end())
			return argsMap[name];
		return std::vector<std::wstring>();
	}

	TEMPLATE
		std::string AM::CArgumentMan<_Str, _Chr>::GetAnsiArg(const std::string &sArgName)
	{
		std::string name = sArgName;
		makeName<std::string>(name);

		std::map< std::string, std::vector<std::string> > argsMap = ToAnsiArgs();
		if (argsMap.find(name) != argsMap.end())
		{
			std::vector<std::string>& args = argsMap[name];
			if (args.size() > 0)
				return args[0];
		}
		return std::string();
	}

	TEMPLATE
		std::wstring AM::CArgumentMan<_Str, _Chr>::GetUnicodeArg(const std::wstring &sArgName)
	{
		std::wstring name = sArgName;
		makeName<std::wstring>(name);

		std::map< std::wstring, std::vector<std::wstring> > argsMap = ToUnicodeArgs();
		if (argsMap.find(name) != argsMap.end())
		{
			std::vector<std::wstring>& args = argsMap[name];
			if (args.size() > 0)
				return args[0];
		}
		return std::wstring();
	}

	TEMPLATE
		bool AM::CArgumentMan<_Str, _Chr>::HasAnsi(std::string &sOutArg, const std::string &sArgName)
	{
		std::string name = sArgName;
		makeName<std::string>(name);

		std::map< std::string, std::vector<std::string> > argsMap = ToAnsiArgs();
		if (argsMap.find(name) == argsMap.end())
		{
			return false;
		}

		std::vector<std::string>& _args = argsMap[name];
		if (_args.size() > 0)
			sOutArg = _args[0];

		return true;
	}

	TEMPLATE
		bool AM::CArgumentMan<_Str, _Chr>::HasAnsi(std::vector<std::string> &vctOutArgs, const std::string &sArgName)
	{
		std::string name = sArgName;
		makeName<std::string>(name);

		std::map< std::string, std::vector<std::string> > argsMap = ToAnsiArgs();
		if (argsMap.find(name) == argsMap.end())
		{
			return false;
		}

		std::vector<std::string>& _args = argsMap[name];
		size_t nSize = _args.size();
		for (size_t i = 0; i < nSize; ++i)
		{
			vctOutArgs.push_back(_args[i]);
		}

		return true;
	}

	TEMPLATE
		bool AM::CArgumentMan<_Str, _Chr>::HasUnicode(std::wstring &sOutArg, const std::wstring &sArgName)
	{
		std::wstring name = sArgName;
		makeName<std::wstring>(name);

		std::map< std::wstring, std::vector<std::wstring> > argsMap = ToUnicodeArgs();
		if (argsMap.find(name) == argsMap.end())
		{
			return false;
		}

		std::vector<std::wstring>& _args = argsMap[name];
		if (_args.size() > 0)
			sOutArg = _args[0];

		return true;
	}

	TEMPLATE
		bool AM::CArgumentMan<_Str, _Chr>::HasUnicode(std::vector<std::wstring> &vctOutArgs, const std::wstring &sArgName)
	{
		std::wstring name = sArgName;
		makeName<std::wstring>(name);

		std::map< std::wstring, std::vector<std::wstring> > argsMap = ToUnicodeArgs();
		if (argsMap.find(name) == argsMap.end())
		{
			return false;
		}

		std::vector<std::wstring>& _args = argsMap[name];
		size_t nSize = _args.size();
		for (size_t i = 0; i < nSize; ++i)
		{
			vctOutArgs.push_back(_args[i]);
		}

		return true;
	}

}

#ifdef _MSC_VER
#pragma  warning(  pop  ) 
#endif

应用实例:

#include "ArgumentMan.h"

void main(int argc, char** argv)
{
	{
		AM::CArgumentMan<std::string, char> am;
		am.AddCmdFlag('/');
		am.AddCmdFlag('-');
		am.AddCmdFlag('\\');
		am.SetIgnoreCase(true);
		am.SetMultiValue(true);
		am.Parse(argc, argv);

		std::map<std::string, std::vector<std::string>> orgArgs = am.GetArgs();
		std::vector<std::string> args = am.GetArgs("name");
		std::string arg = am.GetArg("name");

		std::vector<std::string> hargs;
		am.Has(hargs, "name");

		std::string harg;
		am.Has(harg, "name");

		std::map<std::wstring, std::vector<std::wstring>> wargs = am.ToUnicodeArgs();

		std::vector<std::wstring> hwargs;
		am.HasUnicode(hwargs, L"姓名");
		std::wstring hwarg;
		am.HasUnicode(hwarg, L"姓名");
	}
	{
		wchar_t **pp = new wchar_t *[argc];
		for (int i = 0; i<argc; ++i)
		{
			pp[i] = new wchar_t[256];
			memset(pp[i], '\0', 256);
			std::wstring out;
			AM::Ansi2WideByte(out, argv[i]);
			wcscpy(pp[i], out.c_str());
		}
		AM::CArgumentMan<std::wstring, wchar_t> am;
		am.AddCmdFlag('/');
		am.AddCmdFlag('-');
		am.AddCmdFlag('\\');
		am.SetIgnoreCase(true);
		am.SetMultiValue(true);
		am.Parse(argc, pp);

		std::map<std::wstring, std::vector<std::wstring>> orgArgs = am.GetArgs();
		std::vector<std::wstring> args = am.GetArgs(L"name");
		std::wstring arg = am.GetArg(L"name");

		std::vector<std::wstring> hargs;
		am.Has(hargs, L"name");

		std::wstring harg;
		am.Has(harg, L"name");

		std::map<std::string, std::vector<std::string>> aargs = am.ToAnsiArgs();

		std::vector<std::string> haargs;
		am.HasAnsi(haargs, "姓名");
		std::string haarg;
		am.HasAnsi(haarg, "姓名");
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值