MFC中使用getopt

#ifndef ARGCARGV_H
#define ARGCARGV_H

extern TCHAR * _ppszArgv[];

int __cdecl _ConvertCommandLineToArgcArgv(LPCTSTR lpszSysCmdLine);

#endif //ARGCARGV_H

 

/

//==========================================
// LIBCTINY - Matt Pietrek 2001
// MSDN Magazine, January 2001
//==========================================


// NOTE:  THIS CODE HAS BEEN MODIFIED FOR THIS DEMO APP

// The original source for the LIBCTINY library may be
// found here:  www.wheaty.net


#include "stdafx.h"
#include "argcargv.h"

#define _MAX_CMD_LINE_ARGS  128

TCHAR * _ppszArgv[_MAX_CMD_LINE_ARGS+1];

int __cdecl _ConvertCommandLineToArgcArgv(LPCTSTR lpszSysCmdLine)
{
    if ( lpszSysCmdLine == NULL || lpszSysCmdLine[0] == 0 )
        return 0;

    static LPVOID pHeap = NULL;

    // Set to no argv elements, in case we have to bail out
    _ppszArgv[0] = 0;

    // First get a pointer to the system's version of the command line, and
    // figure out how long it is.
    int cbCmdLine = lstrlen( lpszSysCmdLine );

    // Allocate memory to store a copy of the command line.  We'll modify
    // this copy, rather than the original command line.  Yes, this memory
    // currently doesn't explicitly get freed, but it goes away when the
    // process terminates.
    if (pHeap)                    // in case we are called multiple times
    {
        HeapFree( GetProcessHeap(), 0, pHeap );
        pHeap = NULL;
    }

    pHeap = HeapAlloc( GetProcessHeap(), 0, cbCmdLine*sizeof(TCHAR)+16 );

    if ( !pHeap )
        return 0;

    LPTSTR pszCmdLine = (LPTSTR) pHeap;

    // Copy the system version of the command line into our copy
    lstrcpy( pszCmdLine, lpszSysCmdLine );

    if ( _T('"') == *pszCmdLine )   // If command line starts with a quote ("),
    {                            // it's a quoted filename.    Skip to next quote.
        pszCmdLine++;

        _ppszArgv[0] = pszCmdLine;    // argv[0] == executable name

        while ( *pszCmdLine && (*pszCmdLine != _T('"')) )
            pszCmdLine++;

        if ( *pszCmdLine )        // Did we see a non-NULL ending?
            *pszCmdLine++ = _T('/0');    // Null terminate and advance to next char
        else
            return 0;            // Oops!  We didn't see the end quote
    }
    else    // A regular (non-quoted) filename
    {
        _ppszArgv[0] = pszCmdLine;    // argv[0] == executable name

        while ( *pszCmdLine && (_T(' ') != *pszCmdLine) && (_T('/t') != *pszCmdLine) )
            pszCmdLine++;

        if ( *pszCmdLine )
            *pszCmdLine++ = _T('/0');    // Null terminate and advance to next char
    }

    // Done processing argv[0] (i.e., the executable name).  Now do th
    // actual arguments

    int argc = 1;

    while ( 1 )
    {
        // Skip over any whitespace
        while ( *pszCmdLine && (_T(' ') == *pszCmdLine) || (_T('/t') == *pszCmdLine) )
            pszCmdLine++;

        if ( _T('/0') == *pszCmdLine ) // End of command line???
            return argc;

        if ( _T('"') == *pszCmdLine )   // Argument starting with a quote???
        {
            pszCmdLine++;    // Advance past quote character

            _ppszArgv[ argc++ ] = pszCmdLine;
            _ppszArgv[ argc ] = 0;

            // Scan to end quote, or NULL terminator
            while ( *pszCmdLine && (*pszCmdLine != _T('"')) )
                pszCmdLine++;

            if ( _T('/0') == *pszCmdLine )
                return argc;

            if ( *pszCmdLine )
                *pszCmdLine++ = _T('/0');    // Null terminate and advance to next char
        }
        else                        // Non-quoted argument
        {
            _ppszArgv[ argc++ ] = pszCmdLine;
            _ppszArgv[ argc ] = 0;

            // Skip till whitespace or NULL terminator
            while ( *pszCmdLine && (_T(' ') != *pszCmdLine) && (_T('/t') != *pszCmdLine) )
                pszCmdLine++;

            if ( _T('/0') == *pszCmdLine )
                return argc;

            if ( *pszCmdLine )
                *pszCmdLine++ = _T('/0');    // Null terminate and advance to next char
        }

        if ( argc >= (_MAX_CMD_LINE_ARGS) )
            return argc;
    }
}
///

#ifndef XGETOPT_H
#define XGETOPT_H

extern int optind, opterr;
extern TCHAR *optarg;

int getopt(int argc, TCHAR *argv[], TCHAR *optstring);

#endif //XGETOPT_H

///

///
// if you are using precompiled headers then include this line:
#include "stdafx.h"
///


///
// if you are not using precompiled headers then include these lines:
//#include <windows.h>
//#include <stdio.h>
//#include <tchar.h>
///


#include "XGetopt.h"


///
//
//  X G e t o p t . c p p
//
//
//  NAME
//       getopt -- parse command line options
//
//  SYNOPSIS
//       int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
//
//       extern TCHAR *optarg;
//       extern int optind;
//
//  DESCRIPTION
//       The getopt() function parses the command line arguments. Its
//       arguments argc and argv are the argument count and array as
//       passed into the application on program invocation.  In the case
//       of Visual C++ programs, argc and argv are available via the
//       variables __argc and __argv (double underscores), respectively.
//       getopt returns the next option letter in argv that matches a
//       letter in optstring.  (Note:  Unicode programs should use
//       __targv instead of __argv.  Also, all character and string
//       literals should be enclosed in _T( ) ).
//
//       optstring is a string of recognized option letters;  if a letter
//       is followed by a colon, the option is expected to have an argument
//       that may or may not be separated from it by white space.  optarg
//       is set to point to the start of the option argument on return from
//       getopt.
//
//       Option letters may be combined, e.g., "-ab" is equivalent to
//       "-a -b".  Option letters are case sensitive.
//
//       getopt places in the external variable optind the argv index
//       of the next argument to be processed.  optind is initialized
//       to 0 before the first call to getopt.
//
//       When all options have been processed (i.e., up to the first
//       non-option argument), getopt returns EOF, optarg will point
//       to the argument, and optind will be set to the argv index of
//       the argument.  If there are no non-option arguments, optarg
//       will be set to NULL.
//
//       The special option "--" may be used to delimit the end of the
//       options;  EOF will be returned, and "--" (and everything after it)
//       will be skipped.
//
//  RETURN VALUE
//       For option letters contained in the string optstring, getopt
//       will return the option letter.  getopt returns a question mark (?)
//       when it encounters an option letter not included in optstring.
//       EOF is returned when processing is finished.
//
//  BUGS
//       1)  Long options are not supported.
//       2)  The GNU double-colon extension is not supported.
//       3)  The environment variable POSIXLY_CORRECT is not supported.
//       4)  The + syntax is not supported.
//       5)  The automatic permutation of arguments is not supported.
//       6)  This implementation of getopt() returns EOF if an error is
//           encountered, instead of -1 as the latest standard requires.
//
//  EXAMPLE
//       BOOL CMyApp::ProcessCommandLine(int argc, TCHAR *argv[])
//       {
//           int c;
//
//           while ((c = getopt(argc, argv, _T("aBn:"))) != EOF)
//           {
//               switch (c)
//               {
//                   case _T('a'):
//                       TRACE(_T("option a/n"));
//                       //
//                       // set some flag here
//                       //
//                       break;
//
//                   case _T('B'):
//                       TRACE( _T("option B/n"));
//                       //
//                       // set some other flag here
//                       //
//                       break;
//
//                   case _T('n'):
//                       TRACE(_T("option n: value=%d/n"), atoi(optarg));
//                       //
//                       // do something with value here
//                       //
//                       break;
//
//                   case _T('?'):
//                       TRACE(_T("ERROR: illegal option %s/n"), argv[optind-1]);
//                       return FALSE;
//                       break;
//
//                   default:
//                       TRACE(_T("WARNING: no handler for option %c/n"), c);
//                       return FALSE;
//                       break;
//               }
//           }
//           //
//           // check for non-option args here
//           //
//           return TRUE;
//       }
//
///

TCHAR    *optarg;        // global argument pointer
int        optind = 0;     // global argv index

int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
{
    static TCHAR *next = NULL;
    if (optind == 0)
        next = NULL;

    optarg = NULL;

    if (next == NULL || *next == _T('/0'))
    {
        if (optind == 0)
            optind++;

        if (optind >= argc || argv[optind][0] != _T('-') || argv[optind][1] == _T('/0'))
        {
            optarg = NULL;
            if (optind < argc)
                optarg = argv[optind];
            return EOF;
        }

        if (_tcscmp(argv[optind], _T("--")) == 0)
        {
            optind++;
            optarg = NULL;
            if (optind < argc)
                optarg = argv[optind];
            return EOF;
        }

        next = argv[optind];
        next++;        // skip past -
        optind++;
    }

    TCHAR c = *next++;
    TCHAR *cp = _tcschr(optstring, c);

    if (cp == NULL || c == _T(':'))
        return _T('?');

    cp++;
    if (*cp == _T(':'))
    {
        if (*next != _T('/0'))
        {
            optarg = next;
            next = NULL;
        }
        else if (optind < argc)
        {
            optarg = argv[optind];
            optind++;
        }
        else
        {
            return _T('?');
        }
    }

    return c;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值