A Simple Win32 Command-Line Parser

Environment: VC6, WIN 9x

A Simple Win32 Command-Line Parser

I was disapointed when I first discovered that (non-console) Win32 apps did not have argc and argv. This class is my solution. CmdLineArgs is a subclass of STL vector. After instantiation, it contains the command line args for your app.

argc - size()
argv - operator[]

Here's an example of it's use...


int main ()
{
    CmdLineArgs args;
   
    for (int i = 0; i < args.size(); i++)
        puts (args[i]);

    return 0;
}

Here's a test run of the example code above...

C:>test.exe This "is" a ""test"" "of the parsing" alg"o"rithm.
C:\Test.exe
This
is
a
"test"
of the parsing
alg"o"rithm.

The class...


class CmdLineArgs : public std::vector
{
public:
    CmdLineArgs ()
    {
        // Save local copy of the command line string, because
        // ParseCmdLine() modifies this string while parsing it.
        PSZ cmdline = GetCommandLine();
        m_cmdline = new char [strlen (cmdline) + 1];
        if (m_cmdline)
        {
            strcpy (m_cmdline, cmdline);
            ParseCmdLine(); 
        }
    }
    ~CmdLineArgs()
    {
        delete m_cmdline;
    }

private:
    PSZ m_cmdline; // the command line string

    ////////////////////////////////////////////////////////////////////////////////
    // Parse m_cmdline into individual tokens, which are delimited by spaces. If a
    // token begins with a quote, then that token is terminated by the next quote
    // followed immediately by a space or terminator.  This allows tokens to contain
    // spaces.
    // This input string:     This "is" a ""test"" "of the parsing" alg"o"rithm.
    // Produces these tokens: This, is, a, "test", of the parsing, alg"o"rithm
    ////////////////////////////////////////////////////////////////////////////////
    void ParseCmdLine ()
    {
        enum { TERM  = '\0',
               QUOTE = '\"' };

        bool bInQuotes = false;
        PSZ pargs = m_cmdline;

        while (*pargs)
        {
            while (isspace (*pargs))        // skip leading whitespace
                pargs++;

            bInQuotes = (*pargs == QUOTE);  // see if this token is quoted

            if (bInQuotes)                  // skip leading quote
                pargs++; 

            push_back (pargs);              // store position of current token

            // Find next token.
            // NOTE: Args are normally terminated by whitespace, unless the
            // arg is quoted.  That's why we handle the two cases separately,
            // even though they are very similar.
            if (bInQuotes)
            {
                // find next quote followed by a space or terminator
                while (*pargs && 
                      !(*pargs == QUOTE && (isspace (pargs[1]) || pargs[1] == TERM)))
                    pargs++;
                if (*pargs)
                {
                    *pargs = TERM;  // terminate token
                    if (pargs[1])   // if quoted token not followed by a terminator
                        pargs += 2; // advance to next token
                }
            }
            else
            {
                // skip to next non-whitespace character
                while (*pargs && !isspace (*pargs)) 
                    pargs++;
                if (*pargs && isspace (*pargs)) // end of token
                {
                   *pargs = TERM;    // terminate token
                    pargs++;         // advance to next token or terminator
                }
            }
        } // while (*pargs)
    } // ParseCmdLine()
}; // class CmdLineArgs

Download demo project - 5 Kb



Comments

  • Another approach for C language

    Posted by Aurel on 09/22/2004 09:34am

    hi everyone, and sorry for my poor english.
    
    It's possible to parse the commandLine through the CommandLineToArgW API call, using this function
    
    --------------- snip ----------------------
    #include 
    
    char **argv = NULL;
    	
    /*******************************************************
    WIN32 command line parser function
    ********************************************************/
    int ParseCommandline()
    {
    	int    argc, BuffSize, i;
    	WCHAR  *wcCommandLine;
    	LPWSTR *argw;
    	
    	// Get a WCHAR version of the parsed commande line
    	wcCommandLine = GetCommandLineW();	
    	argw = CommandLineToArgvW( wcCommandLine, &argc);
    
    	// Create the first dimension of the double array
    	argv = (char **)GlobalAlloc( LPTR, argc + 1 );
    	
    	// convert eich line of wcCommandeLine to MultiByte and place them
    	// to the argv[] array
    	for( i=0; i < argc; i++)
    	{
    		BuffSize = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK, argw[i], -1, NULL, 0, NULL, NULL );
    		argv[i] = (char *)GlobalAlloc( LPTR, BuffSize );		
    		WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK, argw[i], BuffSize * sizeof( WCHAR ) ,argv[i], BuffSize, NULL, NULL );
    	}
    	
    	// return the number of argument
    	return argc;
    }
    
    
    /*
     *	WinMain
     */
    int WINAPI WinMain(HINSTANCE hInstance, 
    				   HINSTANCE hPrevInstance, 
    				   LPSTR lpCmdLine, int nShowCmd)
    {
    	int i, argc;
    	
    	argc = ParseCommandline( );
    
    	if( argc < 2 )
    		MessageBox( NULL, "Type some arguments please", "CommandeLine parser", MB_ICONERROR );
    	else
    
    	for( i=0; i < argc; i++ )
    		MessageBox( NULL, argv[i], "Argument list", MB_ICONINFORMATION );
    
    	
    	return TRUE;
    }
    ---------------------------------------

    Reply
  • vector<TCHAR*>

    Posted by Legacy on 10/10/2002 12:00am

    Originally posted by: Keith Tingle

    This approach is more flexible than argc, argv.

    Just port this class to inherit from vector<TCHAR*> (need _tcscpy etc...) and it handles UNICODE environments nicely due to GetCommandLine() returning a TCHAR*.

    Great class, thanks for posting this.

    Reply
  • Beginners error

    Posted by Legacy on 06/13/2002 12:00am

    Originally posted by: HeadHancho

    Did nobody see the leak in the destructor?

    Change "delete m_cmdline;"
    to "delete [] m_cmdline;"

    bye

    Reply
  • can it be done in C language

    Posted by Legacy on 11/07/2001 12:00am

    Originally posted by: venkatesh

    can the parsing of command line argument in win32 progamming be done with the help of c programming language.
    
    if it can then how?

    Reply
  • Should I even be using command line arguments

    Posted by Legacy on 05/18/2001 12:00am

    Originally posted by: Dan Piponi

    If I double click on a file that is associated with an app then the app gets started with the file name as an argument. Is there another way of doing this without using command line arguments. Is there some proper Win32 way of dealing with someone double clicking on a file or dragging a file onto an executable's icon?

    Reply
  • VC++4 and 5

    Posted by Legacy on 12/14/1999 12:00am

    Originally posted by: Douglas Fraser

    Does anyone know how to make this work under Visual C++ versions 4 or 5?

    Reply
  • You can use __argc and __targv or CCommandLineInfo

    Posted by Legacy on 05/17/1999 12:00am

    Originally posted by: Jon Walker

    __argc and __targv are available to non-command line windows apps. Also MFC apps can use CCommandLineInfo (or your own derivative) for more object oriented command line parsing

    Reply
  • __argc, __argv

    Posted by Legacy on 05/07/1999 12:00am

    Originally posted by: John Bundgaard

    Microsoft C++ has __argv and __argc cant these be used?

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • With 81% of employees using their phones at work, companies have stopped asking: "Is corporate data leaking from personal devices?" and started asking: "How do we effectively prevent corporate data from leaking from personal devices?" The answer has not been simple. ZixOne raises the bar on BYOD security by not allowing email data to reside on the device. In addition, Zix allows employees to maintain complete control of their personal device, therefore satisfying privacy demands of valued employees and the …

  • Event Date: April 15, 2014 The ability to effectively set sales goals, assign quotas and territories, bring new people on board and quickly make adjustments to the sales force is often crucial to success--and to the field experience! But for sales operations leaders, managing the administrative processes, systems, data and various departments to get it all right can often be difficult, inefficient and manually intensive. Register for this webinar and learn how you can: Align sales goals, quotas and …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds