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, "姓名"); } }
相关文章推荐
- Java 6 JVM参数选项大全(中文版)
- Linux C函数参考手册(PDF版)
- autoit 命令行参数说明
- 给IE加个参数 永远不怕IE主页被修改
- 写批处理必备的一些命令参数使用技巧
- ASP 调用带参数输出的COM接口
- DIV+CSS经常用到的属性、参数及说明
- C#实现打造气泡屏幕保护效果
- asp获取URL参数的几种方法分析总结[原创]_应用技巧_脚本之家
- 关于C语言中参数的传值问题
- C/C++数据对齐详细解析
- C 语言基础教程(我的C之旅开始了)[三]
- C 语言基础教程(我的C之旅开始了)[七]
- C/C++ 宏详细解析
- c# 方法可变数量的参数
- 用PHP连接MySQL代码的参数说明
- php setcookie(name, value, expires, path, domain, secure) 参数详解
- 用C#生成不重复的随机数的代码
- asp中提示至少一个参数没有被指定值 解决方法