Click here to Skip to main content
Click here to Skip to main content

Object Oriented Command Line Parser

By , 26 Jan 2004
 

Introduction

This class is useful in any object oriented command line applications. It provides an easy way to parse, check and distribute the command line arguments. This class parses the arguments in all these formats:

  • -b
  • -h www.codeproject.com
  • stdafx.cpp
  • -temp:-7

Additionally this class is prepared to parse arguments starting with "--" or "/" at the same time.

Background

The following convention is used to identify the three types of arguments:

  • The arguments that act like a flag ("ls -l") are called empty arguments.
  • Those that also have a value ("netstat -p tcp") are called value arguments.
  • And those who don't have any "-" ("copy a.cpp b.cpp") are called default arguments.

If it's necessary to specify negative numbers (like -temp -7) and to avoid that the engine parses two different empty arguments instead of a value argument, the user can type the command and its value separated by a ":" (like -temp:-7)

Using the code

First of all, the class interface ICmdLineParam must be implemented by all the classes that require to receive the command line arguments. We can implement only a class that receive all the arguments or any number of classes that receive any number of arguments. This interface has two virtual methods: Parse and GetError.

class CConfiguration : public ICmdLineParam
{
public:
    bool Parse(string argument,string value)
    {
        // The parser calls this method to indicate the name 
        // of the arguments and/or
        // the values, only when applicable. The '-' or '/' 
        // of the arguments are eliminated
        // before calling this method.
        // return false only if the parser must stop, on a serious error.
        // return true when the argument is OK or is malformed, 
        // in this second case 
        // the function GetError must return a description, see below.
    }
    std::string GetError()
    {
        // if a fail in command line occurs, this method must return 
        // a description of the error.
        // Ex: "Inaccesible input file", "invalid type of algorithm",..,etc.
        // return an empty string  to indicate that the arguments were OK.
    }
};

Second, a command parser must be declared and also all the objects that must receive the arguments.

    CCommandLineParser parser;
    
    CConfiguration configuration;
    CFileList fileList;
    CErrorEntry errObj;

The most important in this process is to assign every argument to an object. This code register the valid arguments and its type (value, empty or default).

 // Value arguments
 parser.PutValueCommand("out",&configuration);
 parser.PutValueCommand("alg",&configuration);
 
 // Empty arguments
 parser.PutEmptyCommand("h",&errObj);
 parser.PutEmptyCommand("help",&errObj);
 
 // Default arguments, only one object can be asigned that will 
 // receive all the arguments.
 parser.SetDefaultCommand(&fileList);
 
 // Parsing errors.
 parser.SetErrorCommand(&errObj);
 

This code above parse a command line with this format:

[-h] [-help] [-alg md5|sha1] [-out hex] file_1 file_2 ... file_n

Finally the process must start calling the method ParseArguments

if(parser.ParseArguments(argc,argv))
{
    // Application starts here
}

If the user types an invalid argument that is not registered or not type a value in a value argument, then an special argument is passed to the object registered with method SetErrorCommand. Also if one of the classes that implements ICmdLineParam returns a not empty string in GetError method, then another special argument is passed to the error registered class on its method Parse. This special arguments are:

  • UNKNOWN_PARAM argument not registered. Parameter 'value' is assigned with invalid argument.
  • NO_VALUE_PARAM value required. Parameter 'value' is assigned with the value argument.
  • GENERIC_ERROR a ICmdLineParam object returned an error description. Parameter 'value' is assigned with the error description.

This class must output to the user all the descriptions of the errors. See class CError on the demo project for an example.

Points of Interest

This code becomes handy when is necessary to add a new functionality to an already made application. It's easy to add new arguments or new values to previous defined arguments.

History

  • 24 Nov 03 - updated downloads

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Daniel Vela
Spain Spain
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralSuggestion - automatically generate 'usage' textmemberRichardC22 Dec '04 - 14:02 
A pretty good effort at creating a general-purpose command-line parser!
Given that you have a list of required, default and optional parameters then you should be able to auto-create the 'usage' string instead of #define-ing it.
 
Cheers
 
- Richard
GeneralBugmembergrb12 Jan '04 - 12:31 
This doesn't work properly for arguments to options prefixed with a negative sign.
 
E.g.
-temp -7 -humidity 40
(the -7 will become its own argument and cause problems).

GeneralRe: BugmemberDaniel Vela18 Jan '04 - 7:56 
I don't think this is a bug. The negative mark is used as the identifier of an argument.
 
Maybe you could take another simbol (like '=' or any) to represent the negative mark.
 
E.g.
-temp =7 -humidity 40
 
You could program a simple method to subtitute the '=' to '-' after the library parse the arguments.
 
I hope this can help you.
 
Thanks
PD: I was searching for a command line app that use negative numbers as arguments, but i didn't find any where i could look for another solution.
GeneralRe: BugmemberSef Tarbell23 Jan '04 - 6:11 
Try something like this if you need neg/pos numbers included:
 
-temp:-7 -humidity:40
 
you might have to alter the engine to parse the arg which will be returned "temp:7" into it's corresponding pieces.
 
Sef Tarbell
 
"A mind all logic is like a knife all blade, it makes the hand bleed that wields it." --Rabindranath Tagore
GeneralRe: BugmemberDaniel Vela23 Jan '04 - 8:30 
If you say that i can modify the parser to split the command where it finds a ":" and then use the second string as the value of the command,... i think is a good solution. I will study it.
 
Thank you very much.
GeneralRe: BugsussAlexey Yakovlev29 Jan '04 - 9:56 
What's wrong with standard quotes? Shouldn't it be:
-temp "-7" -name "C:/Program Files/Common Files/Microsoft Shared/I think they do it to us on purpose/file.txt"

GeneralRe: BugmemberDaniel Vela29 Jan '04 - 10:31 
In win32 systems the quotes are removed before being notificated to the application.
 
This library will see the parameter as -7, not "-7" and it will be parsed as a command, not a value.
Generalwhy not use '=' for numeric valuesmembers.piras30 Sep '05 - 3:32 
Hi,
would it not be better to have the possibility to set a '='between an argument and his value?
 
I think -temp=-7 -humidity=40 would be a good solution and be much more logical than to use another character to represent the negative mark.
 
Regards
Sandro Piras

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 27 Jan 2004
Article Copyright 2003 by Daniel Vela
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid