Parsing command-line arguments in C?

后端 未结 12 705
眼角桃花
眼角桃花 2020-11-22 16:23

I\'m trying to write a program that can compare two files line by line, word by word, or character by character in C. It has to be able to read in command line options

12条回答
  •  失恋的感觉
    2020-11-22 16:44

    Okay that's the start of long story - made short 'bort parsing a command line in C ...

    /**
    * Helper function to parse the command line
    * @param argc Argument Counter
    * @param argv Argument Vector
    * @param prog Program Instance Reference to fill with options
    */
    bool parseCommandLine(int argc, char* argv[], DuplicateFileHardLinker* prog) {
      bool pathAdded = false;
    
      // iterate over all arguments...
      for ( int i = 1; iQuite mode");
                logInfo(L"  /v\t>Verbose mode");
                logInfo(L"  /d\t>Debug mode");
                return false;
    
                // Log options
              case 'q':
                setLogLevel(LOG_ERROR);
                break;
    
              case 'v':
                setLogLevel(LOG_VERBOSE);
                break;
    
              case 'd':
                setLogLevel(LOG_DEBUG);
                break;
    
              default:
                logError(L"'%s' is an illegal command line option!"
                          "  Use /? to see valid options!", option);
                return false;
              } // switch one-char-option
            } //while one-char-options
          }  //else one vs longer options
        } // if isArgAnOption
    
    // 
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^  So that's it! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // What follows now is are some usefull extras...
    //
        else {
    
    
          // the command line options seems to be a path...
          WCHAR tmpPath[MAX_PATH_LENGTH];
          mbstowcs(tmpPath, argv[i], sizeof(tmpPath));
    
          // check if the path is existing!
          //...
    
          prog->addPath(tmpPath); //Comment or remove to get a working example
          pathAdded = true;
        }
      }
    
      // check for parameters
      if ( !pathAdded ) {
        logError("You need to specify at least one folder to process!\n"
                 "Use /? to see valid options!");
        return false;
      }
    
      return true;
    }
    
    
    
    int main(int argc, char* argv[]) {
    
      try {
        // parse the command line
        if ( !parseCommandLine(argc, argv, prog) ) {
          return 1; 
        }
    
    // I know that sample is just to show how the nicely parse commandline Arguments
    // So Please excuse more nice useful C-glatter that follows now...
      }
      catch ( LPCWSTR err ) {
        DWORD dwError = GetLastError();
        if ( wcslen(err) > 0 ) {
          if ( dwError != 0 ) {
            logError(dwError, err);
          }
          else {
            logError(err);
          }
        }
        return 2;
      }
    }
    
    #define LOG_ERROR               1
    #define LOG_INFO                0
    #define LOG_VERBOSE             -1
    #define LOG_DEBUG               -2
    
    /** Logging Level for the console output */
    int logLevel = LOG_INFO;
    
    void logError(LPCWSTR message, ...) {
      va_list argp;
      fwprintf(stderr, L"ERROR: ");
      va_start(argp, message);
      vfwprintf(stderr, message, argp);
      va_end(argp);
      fwprintf(stderr, L"\n");
    }
    
    
    void logInfo(LPCWSTR message, ...) {
      if ( logLevel <= LOG_INFO ) {
        va_list argp;
        va_start(argp, message);
        vwprintf(message, argp);
        va_end(argp);
        wprintf(L"\n");
      }
    }
    

    Note that this version will also support combining arguments: So instead of writing /h /s -> /hs will also work.

    Sorry for being the n-th person posting here - however I wasn't really satisfied with all the stand-alone-versions I saw here. Well the lib ones are quit nice. So I would prefere libUCW option parser, Arg or Getopt over a home-made ones.

    Note you may change:

    *++argv[i] -> (++argv*)[0] longer less cryptic but still cryptic.

    Okay let's break it down: 1. argv[i]-> access i-th element in the argv-char pointer field

    1. ++*... -> will forward the argv-pointer by one char

    2. ... [0]-> will follow the pointer read the char

    3. ++(...) -> bracket are there so we'll increase the pointer and not the char value itself.

    So nice that In C## the pointers 'died' - long live the pointers !!!

提交回复
热议问题