Save this code here for studying and using it.

Surce code is here.

CmdLine.h File

#pragma once
#include "unicodemacro.h"
#include <vector>
#include <map> namespace Utility
{ // handy little container for our argument vector
struct CmdParam {
std::vector<tstring> strings_;
}; /**
A utility for parsing command lines. This was originally written by Chris Losinger, changes were simply
removing the inheritance from std::map<>, and adding a map as a member
variable instead. then all the VCF related String was replaced with
tstring and can suite both unicode and non-unicode string Example : Our example application uses a command line that has two
required switches and two optional switches. The app should abort
if the required switches are not present and continue with default
values if the optional switches are not present. Sample command line :
MyApp.exe -p1 text1 text2 -p2 "this is a big argument" -opt1 -55 -opt2 Switches -p1 and -p2 are required.
p1 has two arguments and p2 has one. Switches -opt1 and -opt2 are optional.
opt1 requires a numeric argument.
opt2 has no arguments. Also, assume that the app displays a 'help' screen if the '-h' switch
is present on the command line. \code
#include "cmdline.h"
using namespace Utility;
using namespace std;
void show_help()
{
tcout<< _T("This is a help string") <<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
CommandLine cmdLine;
// parse argc,argv
if (cmdLine.SplitLine(argc, argv) < 1)
{
// no switches were given on the command line, abort
ASSERT(0);
exit(-1);
} // test for the 'help' case
if (cmdLine.HasSwitch( _T("-h") ) )
{
show_help();
exit(0);
} // get the required arguments
tstring p1_1, p1_2, p2_1;
try
{
// if any of these fail, we'll end up in the catch() block
p1_1 = cmdLine.GetArgument( _T("-p1") , 0);
p1_2 = cmdLine.GetArgument( _T("-p1") , 1);
p2_1 = cmdLine.GetArgument( _T("-p2") , 0); }
catch (...)
{
// one of the required arguments was missing, abort
ASSERT(0);
exit(-1);
} // get the optional parameters // convert to an int, default to '-1'
int iOpt1Val = tstoi( cmdLine.GetSafeArgument( _T("-optInt"), 0, _T("-1") ).c_str() );
tcout<<iOpt1Val<<endl;
return 0;
}
\endcode
@version 1.0 Chris Losinger
@version 2.0 Jim Crafton
@version 3.0 Marshall Wei
*/
class CommandLine
{
public:
typedef std::map<tstring, CmdParam> CommandLineMap;
typedef std::vector<tstring> CommandLineVector; CommandLine() {}
virtual ~CommandLine() {}
/**
parse the command line into switches and arguments.
@return int number of switches found
*/
int SplitLine( int argc, TCHAR **argv ); int SplitLine( const tstring& commandLine ); int SplitLine( const std::vector<tstring>& commandLine ); /**
was the switch found on the command line ?
\code
ex. if the command line is : app.exe -a p1 p2 p3 -b p4 -c -d p5 call return
---- ------
cmdLine.HasSwitch("-a") true
cmdLine.HasSwitch("-z") false
\endcode
@return bool true if it has the swith, otherwise false
*/
bool HasSwitch( const tstring& aSwitch ) const ; /**
fetch an argument associated with a switch . if the parameter at
index iIdx is not found, this will return the default that you
provide. example :
\code
command line is : app.exe -a p1 p2 p3 -b p4 -c -d p5 call return
---- ------
cmdLine.GetSafeArgument("-a", 0, "zz") p1
cmdLine.GetSafeArgument("-a", 1, "zz") p2
cmdLine.GetSafeArgument("-b", 0, "zz") p4
cmdLine.GetSafeArgument("-b", 1, "zz") zz
\endcode
*/ tstring GetSafeArgument(const tstring& aSwitch, size_t iIdx, const tstring& aDefault) const; /**
fetch a argument associated with a switch. throws an exception
of (int)0, if the parameter at index iIdx is not found. example :
\code
command line is : app.exe -a p1 p2 p3 -b p4 -c -d p5 call return
---- ------
cmdLine.GetArgument("-a", 0) p1
cmdLine.GetArgument("-b", 1) throws (int)0, returns an empty string
\endcode
*/
tstring GetArgument( const tstring& aSwitch, size_t iIdx ) const; tstring GetArgument( size_t index ) const; /**
@return the number of arguments found for a given switch. -1 if the
switch was not found
*/
int GetArgumentCount(const tstring& aSwitch) const; size_t GetArgCount() const {
return m_originalCommandLine.size();
} const std::vector<tstring>& GetOriginalCommandLine() const
{
return m_originalCommandLine;
}
protected:
/**
protected member function
test a parameter to see if it's a switch :
switches are of the form : -x
where 'x' is one or more characters.
the first character of a switch must be non-numeric!
*/
bool IsSwitch(const tstring& param) const; CommandLineMap m_commandLine;
CommandLineVector m_originalCommandLine;
}; }

CmdLine.cpp file

#include "stdafx.h"
#include "cmdline.h" using namespace std; namespace Utility
{
int CommandLine::SplitLine( const std::vector<tstring>& commandLine )
{
m_commandLine.clear();
m_originalCommandLine.clear(); m_originalCommandLine = commandLine; tstring curParam; // current argv[x]
size_t argc = m_originalCommandLine.size();
// skip the exe name (start with i = 1)
for (size_t i = ; i < argc; i++) {
// if it's a switch, start a new CommandLine
if ( IsSwitch(m_originalCommandLine[i])) {
curParam = m_originalCommandLine[i]; tstring arg; // look at next input tstring to see if it's a switch or an argument
if (i + < argc) {
if (!IsSwitch(m_originalCommandLine[i + ])) {
// it's an argument, not a switch
arg = m_originalCommandLine[i + ]; // skip to next
i++;
}
else {
arg = _T("");
}
} // add it
CmdParam cmd; // only add non-empty args
if (arg != _T("") ) {
cmd.strings_.push_back(arg);
} // add the CmdParam to 'this'
std::pair<CommandLineMap::iterator, bool> res = m_commandLine.insert(CommandLineMap::value_type(curParam, cmd)); }
else {
// it's not a new switch, so it must be more stuff for the last switch // ...let's add it
CommandLineMap::iterator theIterator; // get an iterator for the current param
theIterator = m_commandLine.find(curParam);
if (theIterator!=m_commandLine.end()) {
(*theIterator).second.strings_.push_back(m_originalCommandLine[i]);
}
else {
// ??
}
}
} return static_cast<int>( m_commandLine.size() );
} int CommandLine::SplitLine( int argc, TCHAR **argv )
{
std::vector<tstring> args; for ( int j=;j<argc;j++ ) {
args.push_back( tstring(argv[j]) );
} return SplitLine( args );
} int CommandLine::SplitLine( const tstring& commandLine )
{
std::vector<tstring> args;
const TCHAR* P = commandLine.c_str();
const TCHAR* start = P;
const TCHAR* argStart = P; int sz = static_cast<int>( commandLine.size() );
while ( (P - start) < sz ) {
if ( *P == '\"' ) {
P++;
while ( ((P - start) < sz) && (*P != '\"' ) ) {
P++;
}
P++;
} if ( *P == '\"' ) {
continue; //loop again
} if ( *P == ' ' ) {
//argument
//strip out begin/end quotes tstring arg;
const TCHAR* tmpArgStart = argStart;
const TCHAR* tmpArgEnd = tmpArgStart;
while ( tmpArgEnd < P ) {
if ( *tmpArgEnd == '\"' ) {
if ( tmpArgStart != tmpArgEnd ) {
arg.append( tmpArgStart, tmpArgEnd - tmpArgStart );
tmpArgStart = tmpArgEnd;
}
tmpArgStart++;
} tmpArgEnd ++;
} if ( arg.empty() ) {
arg.append( tmpArgStart, tmpArgEnd - tmpArgStart );
} args.push_back( arg ); while ( (*P == ' ') && ((P - start) < sz) ) {
P++;
}
argStart = P;
P--;
} P++;
}
if ( argStart < P ) {
tstring arg;
arg.assign( argStart, P-argStart );
args.push_back( arg );
} return SplitLine( args );
} bool CommandLine::IsSwitch(const tstring& aParam) const
{
if (aParam.empty())
return false; // switches must non-empty
// must have at least one character after the '-' if (aParam.size() <= ) {
return false;
} // switches always start with '-'
if (aParam[]=='-') {
// allow negative numbers as arguments.
// ie., don't count them as switches
return (!isdigit(aParam[]));
}
else {
return false;
}
} bool CommandLine::HasSwitch(const tstring& aSwitch) const
{
CommandLineMap::const_iterator theIterator;
theIterator = m_commandLine.find(aSwitch);
return (theIterator != m_commandLine.end());
} tstring CommandLine::GetSafeArgument(const tstring& aSwitch, size_t index, const tstring& defaultVal) const
{
tstring result; if ( !defaultVal.empty() ) {
result = defaultVal;
} try
{
result = GetArgument(aSwitch, index);
}
catch (...)
{
} return result;
} tstring CommandLine::GetArgument( size_t index ) const
{
tstring result;
if ( (index >= ) && (index < m_originalCommandLine.size()) ) {
result = m_originalCommandLine[index];
}
return result;
} tstring CommandLine::GetArgument( const tstring& aSwitch, size_t index )const
{
if ( HasSwitch( aSwitch ) )
{
CommandLineMap::const_iterator theIterator = m_commandLine.find(aSwitch);
if (theIterator!=m_commandLine.end())
{
if ((*theIterator).second.strings_.size() > index)
{
return (*theIterator).second.strings_[index];
}
}
} throw (int); return _T("");
} int CommandLine::GetArgumentCount(const tstring& aSwitch) const
{
int result = -; if ( HasSwitch(aSwitch) ) {
CommandLineMap::const_iterator theIterator = m_commandLine.find( aSwitch );
if (theIterator!=m_commandLine.end()) {
result = static_cast<int>( (*theIterator).second.strings_.size() );
}
} return result;
}
}

C++: Command Line Processing的更多相关文章

  1. Linux command line exercises for NGS data processing

    by Umer Zeeshan Ijaz The purpose of this tutorial is to introduce students to the frequently used to ...

  2. Getopt::Long - Extended processing of command line options

    use Getopt::Long; my $data   = "file.dat"; my $length = 24; my $verbose; GetOptions (" ...

  3. [笔记]The Linux command line

    Notes on The Linux Command Line (by W. E. Shotts Jr.) edited by Gopher 感觉博客园是不是搞了什么CSS在里头--在博客园显示效果挺 ...

  4. JMeterPluginsCMD Command Line Tool

    There is small command-line utility for generating graphs out of JTL files. It behave just like righ ...

  5. An annotation based command line parser

    Java命令行选项解析之Commons-CLI & Args4J & JCommander http://rensanning.iteye.com/blog/2161201 JComm ...

  6. Creating Node.js Command Line Utilities to Improve Your Workflow

    转自:https://developer.telerik.com/featured/creating-node-js-command-line-utilities-improve-workflow/ ...

  7. stderr: xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

    错误提示: (1). stderr: xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer direc ...

  8. List of Chromium Command Line Switches(命令行开关集)——官方指定命令行更新网址

    转自:http://peter.sh/experiments/chromium-command-line-switches/ There are lots of command lines which ...

  9. xargs: How To Control and Use Command Line Arguments

    参考: http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/ http://linux ...

随机推荐

  1. 【剑指Offer学习】【面试题43 : n 个锻子的点数】

    题目:把n个骰子扔在地上,全部骰子朝上一面的点数之和为s.输入n.打印出s 的全部可能的值出现的概率. 解题思路 解法一:基于通归求解,时间效率不够高. 先把n个骰子分为两堆:第一堆仅仅有一个.还有一 ...

  2. 案例:我行我素购物系统 v1.1

    系统逻辑结构: import java.util.Scanner; public class ShoppingSystem { public static void main(String[] arg ...

  3. 自定义filter包

    在有些时候,你可能需要以你的所有项目进行全局的过滤. 因为你的项目可以设计到互相的依赖和调用 . 修改在tomcat下的conf下的web.xml文件.和在原来的web-inif下的修改一样,添加fi ...

  4. ubuntu 安装 flash player

    ubuntu 软件中心里的 flash , 虽说写的支持 chrome , 但安装总不管用 可运行以下两个命令, 再重启 chrome 浏览器 (注意,一定要把打开的浏览器全部关闭, 再打开才可以) ...

  5. POJ 2891 扩展欧几里德

    这个题乍一看跟剩余定理似的,但是它不满足两两互素的条件,所以不能用剩余定理,也是给了一组同余方程,找出一个X满足这些方程,如果找不到的话就输出-1 因为它不满足互素的条件,所以两个两个的合并,最后合成 ...

  6. 什么是AAC音频格式 AAC-LC 和 AAC-HE的区别是什么

    Advanced Audio Coding(高级音频解码),是一种由MPEG-4标准定义的有损音频压缩格式,由Fraunhofer发展,Dolby, Sony和AT&T是主要的贡献者. 在使用 ...

  7. 【开源java游戏框架libgdx专题】-10-核心库-Viewport

    Viewport类,又称为视口类,主要负责管理游戏相机,处理游戏世界坐标与布景层坐标的换算关系.在移动端开发,不像PC端容易.因为要适配不同分辨率的设备.libgdx处理不同的设备屏幕时,用视口处理舞 ...

  8. 2015-09-22CSS:border、background、表格、超链接、overflow、firebug

    1.CSS的border属性 ⑴定义和用法 border 简写属性在一个声明设置所有的边框属性. 可以按顺序设置如下属性: border-width border-style border-color ...

  9. Android界面刷新方法

    Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中 ...

  10. JS 改变input 输入框样式

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...