• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 606
  • Last Modified:

How to use optind from getopt.h to get the the a argument of the command line?

Hey Experts.

I did some extensive modifications to a program here at work and the last thing I need to do is to force the user of the program to enter the directory that the files will be saved to through the command line.

What I have up until now is attached.
The way my code is everything works fine.

But my boss don't want the directory thing as an option ( -d option), as it is in my code. He mentioned a optind that I can use and wants the user to type something like this:
./MyProgram /path/of/the/directory/ -i orcl -u user -p password

I'm stuck on how to do this.

I need that path information saved in the directory variable I'm using in the code attached and I need to force the user of the program to enter the path to the directory or else the program closes.

Thanks in advance.


bool ClearLogTable::SetOptions( int argc, char** argv )
   {
      char test = 'z';

      while ( true )
      {
         option long_options[] = { {"help", 0, 0, 'h'},
            {"db-user", 1, 0, 'u'},
            {"db-password", 1, 0, 'p'},
            {"db-instance", 1, 0, 'i'},
            {"time", 1, 0, 't'},
            {"separator_char", 1, 0, 's'},
            {"directory", 1, 0, 'd'},
            {0, 0, 0, 0}
         };
         int option_index = 0;
         char c = getopt_long( argc, argv, "hu:p:i:t:s:d:", long_options, &option_index );
         if ( c == -1 )
         {
            break;
         }

         switch ( c )
         {
            case ':':
            case '?':
            case 'h':
            {
               ShowHelp();
               return false;
            }
            break;
            case 'u':
            {
               dbuser = optarg;
            }
            break;
            case 'p':
            {
               dbpassword = optarg;
            }
            break;
            case 'i':
            {
               dbinstance = optarg;
            }
            break;
            case 't':
            {
               m_limitDate = optarg;
            }
            break;
            case 's':
            {
               schar = optarg;
            }
            break;
            case 'd':
            {
               test = 'x';
               directory = optarg;
               if ( directory.rfind("/") == std::string::npos && directory.length() - 5 )
               {
                  directory = directory + "/";
               }
            }
            break;
            default:
            {
               std::cerr << "Unknown error!" << std::endl;
               return EXIT_FAILURE;
            }
            break;
         }

         // If test is different than 'x', user didn't entered the path to the directory
         if ( test != 'x' )
         {
            std::cerr << "The directory wasn't specified." << std::endl;
            return false;
         }
      }

      return true;
   }

Open in new window

0
PDamasceno
Asked:
PDamasceno
  • 6
  • 3
1 Solution
 
Anthony2000Commented:
you can use argv[1], this would be equivalent to optind = 1 and would always give you the value of the first parameter the user specified on the command line.
 
0
 
phoffricCommented:
1) >> and the last thing I need to do is to force the user of the program to enter the directory

   You say that your boss does not want the user to be forced to show the directory, and then you say your boss "wants the user to type something like this:"
    >>    ./MyProgram   /path/of/the/directory/   -i orcl -u user -p password

But the directory is entered here, so that is confusing as to what is required. Is it that if the directory is entered, then it will be found in argv[1] (as mentioned in previous post), but if not entered, then the command line looks like:
      ./MyProgram   -i orcl -u user -p password

If this is the case, then you need a default directory. It may be "." (i.e., the current directory in which the user typed the command).

if( argv[1][0] == '/' )
    directory = argv[1];
0
 
Anthony2000Commented:
phoffric, the boss does not want -d followed by the directory as an optarg, just the directory
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
phoffricCommented:
The problem though is that according to  http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap12.html#tag_12_02    "All options should be preceded by the '-' delimiter character."So, if -d is not permissable, and if you are still trying to include (optionally) the path as the first argument (which goes in argv[1]), then you would need a -d if you still plan on using getopt.       http://www.opengroup.org/onlinepubs/000095399/functions/getopt.html
0
 
Anthony2000Commented:
I think what they want is for the directory to not be an "option", but rather to always be present. Does that make sense?
0
 
Anthony2000Commented:
like the ping command for example
ping www.google.com
0
 
phoffricCommented:
>> I think what they want is for the directory to not be an "option"
It makes sense. I would like additional comment from author to clarify this. When the author wrote:
   "the last thing I need to do is to force the user of the program to enter the directory that the files will be saved to through the command line."

I took that to mean that the user should not have to enter the directory path, that the path was optional by the user (in which case a default directory needs to be defined).

If the optional path without the "-d" is always the first argument, then since it is optional, the path needs to be tested. The path could begin with a '/' or it possibly could begin with a '.' (as in ./abc/xyz, or ../../abc/xyz).

if( argv[1][0] == '/' )
    directory = argv[1];

I would need clarification from the author to be able to better advise. If the "-d" is not allowed by the boss, then using getopt could be a problem. (But parsing arguments is not hard to do without getopt.)
0
 
Anthony2000Commented:
I agree. Also, if the user simply moves the options before the directory parameter, then they could do the following after the "while" statement:
if (optind < argc)
{
 // check to make sure that the input is a valid directory and use it, i.e. argv[optind]
// otherwise, do nothing
}
return;
 
 
0
 
Anthony2000Commented:
This is not tested, just to give you a start. And I am assuming you would make the directory the parameter that is always last on the command line.

bool ClearLogTable::SetOptions( int argc, char** argv )
   {
      char test = 'z';

      while ( true )
      {
         option long_options[] = { {"help", 0, 0, 'h'},
            {"db-user", 1, 0, 'u'},
            {"db-password", 1, 0, 'p'},
            {"db-instance", 1, 0, 'i'},
            {"time", 1, 0, 't'},
            {"separator_char", 1, 0, 's'},
            {0, 0, 0, 0}
         };
         int option_index = 0;
         char c = getopt_long( argc, argv, "hu:p:i:t:s:", long_options, &option_index );
         if ( c == -1 )
         {
            break;
         }

         switch ( c )
         {
            case ':':
            case '?':
            case 'h':
            {
               ShowHelp();
               return false;
            }
            break;
            case 'u':
            {
               dbuser = optarg;
            }
            break;
            case 'p':
            {
               dbpassword = optarg;
            }
            break;
            case 'i':
            {
               dbinstance = optarg;
            }
            break;
            case 't':
            {
               m_limitDate = optarg;
            }
            break;
            case 's':
            {
               schar = optarg;
            }
            break;
            default:
            {
               std::cerr << "Unknown error!" << std::endl;
               return EXIT_FAILURE;
            }
            break;
         }

      }

      if(optind < argc)
      {
         directory = argv[optind];
         if ( directory.rfind("/") == std::string::npos && directory.length() - 5 )
         {
            directory = directory + "/";
         }
      }
      else
      {
         std::cerr << "The directory wasn't specified." << std::endl;
         return false;
      }

      return true;
   }

Open in new window

0
 
PDamascenoAuthor Commented:
Thanks for the insight guys.
Sorry about the long time without a response from me.
I pretty much only check this site on my workplace.
Well, Anthony2000 solution worked fine for me.

But for future reference, and to clarify things to phoffric, my boss said that the user need to enter the path to directory where the files will be saved through the command line. I had to force the user to enter the path name so that the program would only work if the path name was typed.

There.
Thanks again.
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

  • 6
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now