Reading long options in C++ program


 
Thread Tools Search this Thread
Top Forums Programming Reading long options in C++ program
# 1  
Old 03-23-2012
Reading long options in C++ program

I am reading arguments passed to a C++ program which accepts long options.

Long options start with '--', with the value joined with the option by an = sign, with no intervening spaces.

An example is as follows:

Code:
programName --vdz=15.0

I want to store 'vdz' in variable 'key', whereas 15.0 is stored in variable 'value'.

However I also need to find the character string starting from the first occurance of '='. I call it 'after'. Then assign 'value' by going to the second character position onward.

Code is as follows:
Code:
const char* after = strchr(argv[i], '=');
if (after != NULL) const char* value = after + 1;

Well, 'after' can be viewed as the value I want. Thus I am wondering whether I can assign 'value' immediately, or come up with a better descriptive variable name than 'after'.

Any suggestions?
# 2  
Old 03-23-2012
You can eliminate all those variables and cut down on the clutter by doing this...
Code:
const char* value = strchr(argv[i], '=') + 1;

but you shold check if strchr returns a non null pointer...
# 3  
Old 03-23-2012
This is what I have.

Code:
      if (strncmp(argv[i], "--", 2) == 0) {      // First two characters match '--'.

          // If '=' is detected, point to its first occurrence.
          const char* after = strchr(argv[i], '=');

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

          // Detected '--key value'. Set key, and get value from next argument.
          if (after == NULL) {
            SKey = String(argv[i]);    // Convert key to 'String' so we can use ToUpper.
            ++i;                       // Move to next argument (one argument forward).
            if (i == argc) {           // Quit if next argument not found, rather than crashing.
              error("Out of arguments");
              continue;
            }
            value = argv[i];           // Set value from next argument.
            SValue = String(value);

          // Detected '--key=value'. Get value from next argument.
          } else {
            String S = String(argv[i]);
            Search(S, "=", poseq);
            SKey = ToUpper( S.Substr(2, poseq-1) );
            value = after + 1;          // Set user input. "=file"+1 is "file".
            SValue = String(value);
          }

          cout << "Key = " << SKey << ", Value = " << SValue << endl << endl;
          Index += ParseEl(SKey, SValue, Ord);

      } else {

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

      }

So I am wondering what improvements I can have to remove clutter.
# 4  
Old 03-23-2012
As another suggestion, try the getopt_long(3) function, if your system supports it. Maybe you could even build your own C++ wrapper to this function.
# 5  
Old 03-26-2012
Quote:
Originally Posted by pflynn
As another suggestion, try the getopt_long(3) function, if your system supports it. Maybe you could even build your own C++ wrapper to this function.
Sounds good idea. I am using g++, so should have this option. Would you be so kind to give me an example for it?

---------- Post updated at 05:37 AM ---------- Previous update was at 04:53 AM ----------

Currently for the main programs I call

Code:
Parsing  Pc(argc, argv);

[CODE]

Class Parsing is a general function that accepts any arguments, and the checks are done by calling
Code:
Pc.GetString("CMOD", S))

This checks through all arguments for CMOD which is the Key and returns S, which is the value (in this case the file name).

Similarly to get a real value, I use

Code:
Pc.GetReal("VDX", Vdx) )

The current program is as follows
Code:

// -- Program --------------------------------------------------------------------------------------
//
//    getvel
//      Creates an "x z v" file for plotting the sound speed values using GMT.
//
// -- Usage ----------------------------------------------------------------------------------------
//
//    ./getvel Args
//
//    Mandatory Arguments:
//
//    Optional Arguments:
//
// -- History --------------------------------------------------------------------------------------
//
//    V01 - DEC 1999 - Luca D'Auria
//          Initial release.
//    V02 - SEP 2008 - Luca Elia
//          Version fixed for g++ 4.3.0.
//    V03 - MAY 2009 - Christopher Dimech
//          Adopted C++ coding standards based on the IBM Standard C++
//          Library Reference Guide and the Ellementel Telecommunication
//          Systems Laboratory C++ Style Guide.
//    V04 - NOV 2009 - Luca D'Auria
//          Code changes after visit to RISSC-Lab.
//    V05 - JUL 2011 - Christopher Dimech
//          Adopted UML 2.3 for documenting class structure.
//
// -------------------------------------------------------------------------------------------------

#include "Parsing.hh"
#include "GenFunc.hh"
#include "VelMod.hh"
#include "common.hh"

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

const int  DefKx = 20;
const int  DefKz = 20;
const int  DefKI = 20;

const char  *DOC[] = {
"",
"-- Program --------------------------------------------------------------------------------------",
"",
"   GetVel",
"     Creation of a \"x z v\" file",
"",
"-- Usage ----------------------------------------------------------------------------------------",
"",
"   getvel model [arguments]",
"",
"     model",
"       Velocity model file (required)",
"",
"     vdx",
"       Interval in x direction in velocity file",
"",
"     kx",
"       Interval calculated with vdx = Lx / kx (Default is 20).",
"",
"     vdz",
"       Interval in z direction in velocity file or",
"",
"     kz",
"       Interval calculated with vdz = Lz / kz (Default is 20).",
"",
"     vdi",
"       Interval along interface",
"",
"     ki",
"       Interval calculated with vdi = Li / ki (Default is 20).",
"",
"     vel or velp",
"       File with P wave velocity in 'x z v' format",
"",
"     vels",
"       File with S wave velocity in 'x z v' format",
"",
"     lay",
"       (on/off). If on output files are in \"x z v l\" format, where l",
"       is the active layer.",
"",
"     intf",
"       Output file for interfaces in 'x z' format, separated by '>'",
"",
"    see HTML help for more details",
"",
"-------------------------------------------------------------------------------------------------",
"",
NULL
};

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

int  main(
  int  argc,
  char*  argv[]) {

  if (argc < 2) {                                         // Print documentation
    FILE*  pipe;
    const char**  ptr = DOC;
    pipe = popen("more", "w");
    while (*ptr) { (void)fprintf(pipe, "%s\n", *ptr++); }
    pclose(pipe);
    exit(1);
  }

  // -- Reading command line arguments -------------------------------------------------------------

  bool  lay = false;
  int  Kx;
  int  Kz;
  int  KI;
  Real  Lx;
  Real  Lz;
  Real  Vdx;
  Real  Vdz;
  Real  Idx;
  Vect2  Xi;
  Vect2  Xf;
  String  S;
  Velmod  vm;
  Parsing  Pc(argc, argv);

  // -----------------------------------------------------------------------------------------------

  if (Pc.GetString("CMOD", S)) {
    ifstream  model(S);
    Parsing  Pm(model);
    vm.Read(Pm);
    Pm.GetVect2("XI", Xi);
    Pm.GetVect2("XF", Xf);
    Lx = Xf.X - Xi.X;
    Lz = Xf.Z - Xi.Z;
  } else {
    error("Bad Vdx parameter");
  }

  // -----------------------------------------------------------------------------------------------

  if ( !Pc.GetReal("VDX", Vdx) ) {
      if ( !Pc.GetInt("KX", Kx) ) { Kx = DefKx; }
      if (Kx < 0) { error("Bad Kx parameter"); }
      Vdx = Lx / Kx;
  } else {
      Kx = (int)rint(Lx / Vdx);
      Vdx = Lx / Kx;
  }
  if (Vdx < 0) { error("Bad Vdx parameter"); }

  // -----------------------------------------------------------------------------------------------

  if ( !Pc.GetReal("VDZ", Vdz) ) {
      if ( !Pc.GetInt("KZ", Kz) ) { Kz = DefKz; }
      if (Kz < 0) { error("Bad Kz parameter"); }
      Vdz = Lz / Kz;
  } else {
      Kz = (int)rint(Lz / Vdz);
      Vdz = Lz / Kz;
  }
  if (Vdz < 0) { error("Bad Vdz parameter"); }

  // -----------------------------------------------------------------------------------------------

  if ( !Pc.GetReal("IDX", Idx) ) {
      if ( !Pc.GetInt("KI", KI) ) { KI = DefKI; }
      if (KI < 0) { error("Bad KI parameter"); }
      Idx = Lx / KI;
  } else {
      KI = (int)rint(Lx / Idx);
      Idx = Lx / KI;
  }
  if (Idx < 0) { error("Bad Idx parameter"); }

  // -----------------------------------------------------------------------------------------------

  bool  bvp = true;
  bool  bvs = true;
  bool  bintf = true;
  ofstream  velp;
  ofstream  vels;
  ofstream  intf;

  if (Pc.GetString("VEL", S)) {
      velp.open(S);
      if (velp.bad()) { error("Bad VEL file"); }
  } else if (Pc.GetString("VELP", S)) {
      velp.open(S);
      if (velp.bad()) { error("Bad VELP file"); }
  } else {
      bvp = false;
  }

  // -----------------------------------------------------------------------------------------------

  if (Pc.GetString("VELS", S)) {
      vels.open(S);
      if ( vels.bad() ) { error("Bad VELS file"); }
  } else {
      bvs = false;
  }

  // -----------------------------------------------------------------------------------------------

  if (Pc.GetString("INTF", S)) {
      intf.open(S);
      if (intf.bad()) { error("Bad INTF file"); }
  } else {
      bintf = false;
  }

  // -----------------------------------------------------------------------------------------------

  if (Pc.GetString("LAY", S)) {

      S.ToUpper();

      if (S == String("ON")) { lay = true;
      } else if (S != String("OFF")) { error("Bad LAY parameter"); }

  }

  // -----------------------------------------------------------------------------------------------

  int  i, j;
  Real  v, x, z;

  if (bvp) {
      for (i = 0; i <= Kx; i++) {
          for (j = 0; j <= Kz; j++) {
              x = Xi.X + (i * Vdx);
              z = Xi.Z + (j * Vdz);
              v = vm.VP(x, z);
              velp << x << ' ' << z << ' ' << v;

              if (lay)  { velp << ' ' << vm.GetLayer(x, z) << endl;
              } else  { velp << endl; }
          }
      }
      velp.close();
  }

  // -----------------------------------------------------------------------------------------------

  if (bvs) {
      for (i = 0; i <= Kx; i++) {

          for (j = 0; j <= Kz; j++) {

              x = Xi.X + (i * Vdx);
              z = Xi.Z + (j * Vdz);
              v = vm.VS(x, z);
              vels << x << ' ' << z << ' ' << v;

              if (lay)  { vels << ' ' << vm.GetLayer(x, z) << endl;
              } else  { vels << endl; }

          }
      }
      vels.close();
  }

  // -----------------------------------------------------------------------------------------------

  if (bintf) {
      int  NLay = vm.GetNLayers(), Lay;
      intf << '>' << endl;
      for (Lay = 1; Lay <= NLay; Lay++) {
          for (i = 0; i <= KI; i++) {
              x = Xi.X + i * Idx;
              z = vm.Z(x, i);
              intf << x << ' ' << z << endl;
          }
          intf << '>' << endl;
      }
      intf.close();
  }

  return (0);

}

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

---------- Post updated at 05:37 AM ---------- Previous update was at 05:37 AM ----------

I have started coding an simple test

Code:
#include "Parsing.hh"
#include "GenFunc.hh"
#include "VelMod.hh"
#include "common.hh"

#include <stdlib.h>    // for exit
#include <unistd.h>    // for getopt_long

int  main(
  int  argc,
  char*  argv[]) {


  if (argc < 2) {                                         // Print documentation
    FILE*  pipe;
    const char**  ptr = DOC;
    pipe = popen("more", "w");
    while (*ptr) { (void)fprintf(pipe, "%s\n", *ptr++); }
    pclose(pipe);
    exit(1);
  }

// -------------------------------------------------------------------------------------------------

    int c;
    int digit_optind = 0;
    int aopt = 0, bopt = 0;
    char *copt = 0, *dopt = 0;
    static struct option long_options[] = {
        {"add", 1, 0, 0},
        {"append", 0, 0, 0},
        {"delete", 1, 0, 0},
        {"verbose", 0, 0, 0},
        {"create", 1, 0, 'c'},
        {"file", 1, 0, 0},
        {NULL, 0, NULL, 0}
    };
    int option_index = 0;
    while ((c = getopt_long(argc, argv, "abc:d:012",
                 long_options, &option_index)) != -1) {
        int this_option_optind = optind ? optind : 1;
        switch (c) {
        case 0:
            printf ("option %s", long_options[option_index].name);
            if (optarg)
                printf (" with arg %s", optarg);
            printf ("\n");
            break;
        case '0':
        case '1':
        case '2':
            if (digit_optind != 0 && digit_optind != this_option_optind)
              printf ("digits occur in two different argv-elements.\n");
            digit_optind = this_option_optind;
            printf ("option %c\n", c);
            break;
        case 'a':
            printf ("option a\n");
            aopt = 1;
            break;
        case 'b':
            printf ("option b\n");
            bopt = 1;
            break;
        case 'c':
            printf ("option c with value '%s'\n", optarg);
            copt = optarg;
            break;
        case 'd':
            printf ("option d with value '%s'\n", optarg);
            dopt = optarg;
            break;
        case '?':
            break;
        default:
            printf ("?? getopt returned character code 0%o ??\n", c);
        }
    }
    if (optind < argc) {
        printf ("non-option ARGV-elements: ");
        while (optind < argc)
            printf ("%s ", argv[optind++]);
        printf ("\n");
    }
    exit (0);


Last edited by kristinu; 03-26-2012 at 08:23 AM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Reading a long literal continued next line

I am trying to identify all messages or prompts from a number of COBOL programs and they can usually be identified by a pair of double quotes on one line. However, sometimes the literal will not be finished on the first line but after a dash in column 7 of the next line, the literal will be... (6 Replies)
Discussion started by: wbport
6 Replies

2. Shell Programming and Scripting

Perl :: Getopt::Long in the program

While going through some of the perl script... I had found the below line.. use Getopt::Long; my $GetOptionsReturnCode = GetOptions ( '<>' => sub { push(@unknownArg, @_); }, 'h|help' => sub { &helpMessage(); exit 0; }, ); Could anyone please explain the above one ... (1 Reply)
Discussion started by: scriptscript
1 Replies

3. Shell Programming and Scripting

How to display a message if program hangs(takes too long)

I have a ksh script (script1) that calls another ksh script (script2). If script2.ksh hangs or takes too long to execute I want script1.ksh to kill the call to script2.ksh and instead just display "Script2 can't run right now". Could someone help me with coding this? (1 Reply)
Discussion started by: mrskittles99
1 Replies

4. Shell Programming and Scripting

Reading command line options from bash script

I have the following code and I am calling it using ./raytrac.bash -u and getting problems. For some reason opt_usage is still 0. opt_usage=0 iarg=0 narg=$# while (($iarg < $narg)) do (( iarg = $iarg + 1 )) arg=$argv usrInputFlag=`echo $arg | awk '/=/ {print 1}; ! /=/... (22 Replies)
Discussion started by: kristinu
22 Replies

5. Shell Programming and Scripting

Reading command options one by one

Hi, Just some questions on the script below...? Given: bash-2.03$ command -a option1 name1 name2 ParseOptions() { local Len=${#@} local Ctr=2 #always start at 2 local Name=() local Iter=0 while ; do if <- Is this correct? so I can get the $2... (2 Replies)
Discussion started by: h0ujun
2 Replies

6. Shell Programming and Scripting

using getopt for both short and long options

Hi , I am using getopt for both short and long options as below SHORTOPTS="a:c" LONGOPTS="alpha:,charlie" OPTS=$(getopt -o $SHORTOPTS --longoptions $LONGOPTS -n "$progname" -- "$@") eval set -- "$OPTS" while ; do case $1 in -a|--alpha) echo "-a or --alpha... (1 Reply)
Discussion started by: padmisri
1 Replies

7. Shell Programming and Scripting

using getopt for both short and long options

Hi , I am using getopt for both short and long options as below SHORTOPTS="a:c" LONGOPTS="alpha:,charlie" OPTS=$(getopt -o $SHORTOPTS --longoptions $LONGOPTS -n "$progname" -- "$@") eval set -- "$OPTS" while ; do case $1 in -a|--alpha) echo "-a or --alpha... (1 Reply)
Discussion started by: padmisri
1 Replies

8. Shell Programming and Scripting

using getopt for both short and long options

Hi , I am using getopt for both short and long options as below SHORTOPTS="a:c" LONGOPTS="alpha:,charlie" OPTS=$(getopt -o $SHORTOPTS --longoptions $LONGOPTS -n "$progname" -- "$@") eval set -- "$OPTS" while ; do case $1 in -a|--alpha) echo "-a or --alpha... (0 Replies)
Discussion started by: padmisri
0 Replies

9. Shell Programming and Scripting

Help with shell script to run the commands reading options from local file

I have to use shell script to run series of commands on another unix box by connecting through SSH and giving user credentials. For running commands on remote machine I have to use options reading from a local file. Process: Connecting to remote unix server <host1.ibm.com> through ssh Login: ... (2 Replies)
Discussion started by: itsprout
2 Replies

10. UNIX for Dummies Questions & Answers

reading long filenames from nero to AIX

One of my colleagues is having an issue moving files between a windows box and the AIX servers in the office. The filenames are being truncated though i don't know to what extent. He's using Nero to burn the CD and I think he mentioned he's using Joliet. I found another thread that shows a... (1 Reply)
Discussion started by: categoryzd
1 Replies
Login or Register to Ask a Question