Solved

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

Posted on 2010-08-18
10
578 Views
Last Modified: 2012-05-10
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
Comment
Question by:PDamasceno
  • 6
  • 3
10 Comments
 
LVL 8

Expert Comment

by:Anthony2000
Comment Utility
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
 
LVL 32

Expert Comment

by:phoffric
Comment Utility
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
 
LVL 8

Expert Comment

by:Anthony2000
Comment Utility
phoffric, the boss does not want -d followed by the directory as an optarg, just the directory
0
 
LVL 32

Expert Comment

by:phoffric
Comment Utility
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
 
LVL 8

Expert Comment

by:Anthony2000
Comment Utility
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 8

Expert Comment

by:Anthony2000
Comment Utility
like the ping command for example
ping www.google.com
0
 
LVL 32

Expert Comment

by:phoffric
Comment Utility
>> 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
 
LVL 8

Expert Comment

by:Anthony2000
Comment Utility
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
 
LVL 8

Accepted Solution

by:
Anthony2000 earned 500 total points
Comment Utility
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
 

Author Comment

by:PDamasceno
Comment Utility
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

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now