Reading command line arguments and setting up values if option not provided

I have a C++ program. I read command line arguments, but if the value is not supplied, I default or make a calculation. Let's say I set it to a default value.

I can code this in several ways. Here I show three ways. What would be the best way for maintaining this code? The program will get very large with lot of options, so need a scheme that can facilitate the development and maintenance of the code .

   Parsing  Pc(argc, argv);           // Pass all arguments
 
  const double  DefdAng = 2.0;
   double  dAng = DefdAng;
   if (Pc.GetDouble("DANG", dAng)) {   // User supplied value for dAng using DANG option. 
       cout << "User supplied dAng value = " << dAng << endl;
  }
 
  Parsing  Pc(argc, argv);           // Pass all arguments

  const double  DefdAng = 2.0;
  double  dAng;
  if (Pc.GetDouble("DANG", dAng)) {   // User supplied value for dAng using DANG option. 
      cout << "User supplied dAng value = " << dAng << endl;
  else {
      dAng = DefdAng;
       cout << "dAng set to default value of " << dAng << endl;
   }
   Parsing  Pc(argc, argv);           // Pass all arguments
 
  const double  DefdAng = 2.0;
   double  dAng;
   if (!Pc.GetDouble("DANG", dAng)) {
       dAng = DefdAng;
         cout << "dAng set to default value of " << dAng << endl;
     else {      // User supplied value for dAng using DANG option. 
      cout << "User supplied dAng value = " << dAng << endl;
    }
 

You've not defined any of your classes as usual so I have no idea what any of your code is doing.

The easiest way to set a default is to just set the value in the first place. If there's another value found, overwrite the original.

int var=32;

if(has_value) var=get_value;

Here is a bit about class Parsing

#ifndef Parsing_hh
#define Parsing_hh

#include <iostream>
#include <fstream>
#include <string.h>

#include "ParseEl.hh"
#include "DynBaseObj.hh"
#include "List.hh"
#include "Stack.hh"
#include "Tree.hh"
#include "Vect2.hh"
#include "Vector.hh"
#include "String.hh"
#include "common.hh"

class Parsing {

private:

  int  Length;                         //
  int  Ptr;                            //
  List<ParseEl>  Index;                //

public:

  Parsing();                           //

  Parsing(                             //
    const int  argc,
    char*  argv[]);

  void  ParseCmd(                      // Read command line arguments.
    const int  argc,
    char*  argv[]);

  bool  GetDouble(                     // Get a double precision number.
    const String&  Id,
    double&  d,
    const int  ord1,
    const int  ord2,
    const int  ord3);

  bool  GetDouble(                     // Get a double precision number.
    const char*  Id,
    double&  d,
    const int  ord1,
    const int  ord2,
    const int  ord3);

private:

  bool  GetDouble(                     // Get a double precision number.
    const char*  Id,
    double&  d,
    const List<int>&  ord);

};

////////////////////////////////////////////////////////////////////////////////////////////////////

inline Parsing::Parsing() {
  Ptr = 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

Parsing::Parsing(
  const int  argc,
  char*  argv[]) {

  ParseCmd(argc, argv);

}

////////////////////////////////////////////////////////////////////////////////////////////////////

// Reading arguments from the command line

void  Parsing::ParseCmd(
  const int  argc,
  char*  argv[]) {

  int  i;
  int  StrSize;                        // Size of string
  int  EndsSize;                       // Size of string
  int  poseq;
  const char* Name;
  const char* Ends;
  String  SName;
  String  SEnd;

  List<int>  Ord;
  Ord += 0;

  for (i = 1; i < argc; i++) {

      // First character is '?', e.g. "?abcd"[0] is '?'.
      if (argv[0] == '?') {

          ifstream ifs(argv+1);     // "?abcd"+1 is "abcd", so open filename "abcd".
          if ( ifs.bad() ) error("Error including file " + String(argv) );
          else ParseFile(ifs);

      }                                // end of code block. ifs closes here.

      // First 2 chars are '-'. A zero value indicates that the characters compared in both
      // strings are all equal.
      else if (strncmp(argv, "--", 2) == 0)
      {

          // Pointer to first occurrence of '='
          // strchr("--asdf=b", '=') is "=b". If '=' is not found, function returns null pointer.
          const char* After = strchr(argv, '=');

//          String Name;                 // Make it a 'String' so we can use ToUpper.

          // '=' is not found. Get user input from next argument.
          if (After == NULL)
          {
            SName = String(argv);   // Conversion of 'Name' to a 'String' so we can use ToUpper.
            i++;                       // ++i is more efficient than i++.
            if (i == argc) {           // If next argument not found, quit instead of crashing.
              error("Out of arguments");
              continue;
            }
            Ends = argv;            // Set user input
            SEnd = String(Ends);

          // '=' is found.
          } else {
            String S = String(argv);
            Search(S, "=", poseq);
            SName = ToUpper( S.Substr(2, poseq-1) );
            Ends = After + 1;          // Set user input. "=file"+1 is "file".
            SEnd = String(Ends);
          }

          cout << "Name = " << SName << ", Ends = " << SEnd << endl << endl;
          Index += ParseEl(SName, SEnd, Ord);

      } else {

          String Msg = "Long options must be introduced by a double dash '--'. '";
          error(Msg + String(argv) + "'");

      }

  }

  Ptr = 0;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

inline bool  Parsing::GetDouble(
  const String&  Id,
  double&  d,
  const int  ord1 = 0,
  const int  ord2 = 0,
  const int  ord3 = 0) {

  return GetDouble( (char *)Id, d, ord1, ord2, ord3 );

}

////////////////////////////////////////////////////////////////////////////////////////////////////

bool  Parsing::GetDouble(
  const char*  Id,
  double&  d,
  const int  ord1 = 0,
  const int  ord2 = 0,
  const int  ord3 = 0 ) {

  List<int>  L;

  if (ord1 != 0) {
      L += ord1;
      if (ord2 != 0) {
          L += ord2;
          if (ord3 != 0) { L += ord3; }
      }
  }

  return GetDouble(Id, d, L);

}

////////////////////////////////////////////////////////////////////////////////////////////////////

bool  Parsing::GetDouble(
  const char*  Id,
  double&  d,
  const List<int>&  ord) {

  int  j;
  int  found = -1;
  int  HId = Hash(Id);

  j = Ptr;
  if (Index.size() == 0) { return false; }

  do {

      if ( (Index[j].Hash == HId) && (Index[j].Type == PARAM)
        && (Index[j].Name == String(Id)) && (Index[j].Ord == ord) ) {
          found = j;
      }

      j++;
      if (j == Index.size()) { j = 0; }

  } while ((found == -1) && (j != Ptr));

  if (found == -1) { return false; }
  Index[found].Str.Rewind();
  Index[found].Str >> d;
  Ptr = found;
  if (Ptr == Index.size()) { Ptr = 0; }
  return true;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

#endif

---------- Post updated at 08:16 PM ---------- Previous update was at 08:05 PM ----------

Take all command line arguments defined as --name=value.
Stores the list of names and the corresponding values.

Checks if DANG is present in the name list. If successful,
the function will return true and the value returned in the
variable dang. Otherwise returns false.