Solved

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

Posted on 2010-08-18
10
581 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 500 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

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho‚Ķ
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…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

735 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