Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

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

Posted on 2010-08-18
10
Medium Priority
?
596 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
ID: 33467920
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
ID: 33468245
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
ID: 33468284
phoffric, the boss does not want -d followed by the directory as an optarg, just the directory
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 32

Expert Comment

by:phoffric
ID: 33468292
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
ID: 33468318
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
 
LVL 8

Expert Comment

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

Expert Comment

by:phoffric
ID: 33468428
>> 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
ID: 33468480
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 2000 total points
ID: 33468626
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
ID: 33473639
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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

876 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