CCommandLine.h
#pragma once
#include <wtypesbase.h>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <tchar.h>
#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif
class CCommandLine
{
public:
// 获取命令行
static _tstring GetCommand();
//
// @brief: 获取命令行键值对
// @param: chDelim 键值对分割符号
// @ret: std::map<_tstring, _tstring> 命令行键值对
static std::map<_tstring, _tstring> GetCommandKeyValue(TCHAR chDelim);
private:
// 宽字符串转换
static _tstring _WStrToTStr(const std::wstring& str);
static std::wstring _TStrToWStr(const _tstring& str);
// 宽字符转其他
static std::string _WStrToMultiStr(UINT CodePage, const std::wstring& str);
// 其他转宽字符
static std::wstring _MultiStrToWStr(UINT CodePage, const std::string& str);
};
CCommandLine.cpp
#include "CCommandLine.h"
_tstring CCommandLine::GetCommand()
{
_tstring strResult;
LPCTSTR pCommandLine = ::GetCommandLine();
if (nullptr != pCommandLine)
{
strResult = pCommandLine;
}
return strResult;
}
std::map<_tstring, _tstring> CCommandLine::GetCommandKeyValue(TCHAR chDelim)
{
std::map<_tstring, _tstring> vResult;
_tstring strCommandLine = ::GetCommandLine();
do
{
if (strCommandLine.empty())
{
break;
}
int nArgs = 0;
LPWSTR* pArglist = nullptr;
std::wstring strCommand = _TStrToWStr(strCommandLine);
pArglist = ::CommandLineToArgvW(strCommand.c_str(), &nArgs);
if (nullptr == pArglist)
{
break;
}
for (int i = 1; i < nArgs; i++)
{
_tstring strName = _WStrToTStr(pArglist[i]);
_tstring strValue;
// 单个字符则认为只有值名, 没有值数据
if (strName.size() > 1)
{
size_t nPos = strName.find_first_of(chDelim, 1);
if (_tstring::npos != nPos && nPos > 0)
{
strValue = strName.substr(nPos + 1);
strName.resize(nPos);
}
}
// 检查插入结果, 插入失败则更新值数据
auto pairInsert = vResult.insert(std::make_pair(strName, strValue));
if (!pairInsert.second)
{
pairInsert.first->second = strValue;
}
}
::LocalFree(pArglist);
} while (false);
return vResult;
}
std::wstring CCommandLine::_TStrToWStr(const _tstring& str)
{
#ifdef _UNICODE
return str;
#else
return _MultiStrToWStr(CP_ACP, str);
#endif
}
_tstring CCommandLine::_WStrToTStr(const std::wstring& str)
{
#ifdef _UNICODE
return str;
#else
return _WStrToMultiStr(CP_ACP, str);
#endif
}
std::string CCommandLine::_WStrToMultiStr(UINT CodePage, const std::wstring& str)
{
//计算缓冲区所需的字节长度
int cbMultiByte = ::WideCharToMultiByte(CodePage, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
std::string strResult(cbMultiByte, 0);
//成功则返回写入到指示的缓冲区的字节数
size_t nConverted = ::WideCharToMultiByte(CodePage, 0, str.c_str(), (int)str.size(), &strResult[0], (int)strResult.size(), NULL, NULL);
//调整内容长度
strResult.resize(nConverted);
return strResult;
}
std::wstring CCommandLine::_MultiStrToWStr(UINT CodePage, const std::string& str)
{
//计算缓冲区所需的字符长度
int cchWideChar = ::MultiByteToWideChar(CodePage, 0, str.c_str(), -1, NULL, 0);
std::wstring strResult(cchWideChar, 0);
//成功则返回写入到指示的缓冲区的字符数
size_t nConverted = ::MultiByteToWideChar(CodePage, 0, str.c_str(), (int)str.size(), &strResult[0], (int)strResult.size());
//调整内容长度
strResult.resize(nConverted);
return strResult;
}