您的位置:首页 > 编程语言 > C语言/C++

c++参数管理

2014-03-06 20:39 369 查看
/*
 * 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, const char* locale="")
{
/*
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()));*/

size_t nLen = wcslen(wstrcode) * 2;
if (nLen == 0)
{
out.resize(0);
return true;
}

setlocale(LC_ALL, locale);
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, "");

return true;
}

//ansi 转 Unicode
bool Ansi2WideByte(std::wstring& out, const char* strAnsi, const char* locale = "")
{
/*
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()));
*/

size_t nLen = strlen(strAnsi) * 2;
if (nLen == 0)
{
out.resize(0);
return true;
}

setlocale(LC_ALL, locale);
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, "");

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, "姓名");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c 参数