Combine GetOpt And Variadic Function In C


 
Thread Tools Search this Thread
Top Forums Programming Combine GetOpt And Variadic Function In C
# 1  
Old 02-20-2019
Combine GetOpt And Variadic Function In C

Been a while since my last post. Had a laptop die with my last project and still working to get it back. In the meantime I started another.

In my main function I define some arguments with getopt:
Code:
int main ( int argc, char **argv) {
  int option_index = 0;
  char *fname = "./commands";

  if(argc == 1){ 
	  //pass: error defined in file_open function.
	  file_open(fname);
  } 
  
while(optind < argc) {
  if(( option_index = getopt(argc, argv, "f:h:u:p:k:o:w:e")) != -1){	
   switch(option_index){
     case 'f':
       file_open(optarg);	     
       break;	     
     case 'h':
       host_open(optarg);
       break;
     case 'u':
       user_open(optarg);
       break;
     case 'p':
       port_open(optarg);
       break;
     case 'w':
       pass_open(optarg);
       break;
     default:
      usage();
      break;
     } 
   }
   else {
      file_open(fname);
      optind++;
   }
}
  
  return 0;
}

The above is missing some optional arguments for brevity. Since there were optional arguments, I found I would need to use a variadic function with something like this:
Code:
void args(char *howmany, ...){
  
  va_list ap;
  char *host, *user, *pass, *port;
  va_start(ap, howmany);
  
  while(*howmany) { 
     switch(*(howmany++)){
	     case 'h':
		host = va_arg(ap, char *);		
		printf("%s\n", host);
		break;
	     case 'u':
		user = va_arg(ap, char *);
		printf("%s\n", user);
		break;
	     case 'w':
		pass = va_arg(ap, char *);
		printf("%s\n", pass);
		break;
	     case 'p':
	        port = va_arg(ap, char *);
	        printf("%s\n", port);
	        break;
	     }	
  }

  va_end(ap);  

}

Looking at these I could see they were very similar with their switch statements. Instead of calling a function from main and then using that function to call the variadic function, it seems there should be a way to combine them. I'm just having trouble getting the logic/syntax for this and not finding much with my google searches.

Any suggestions much appreciated.
# 2  
Old 02-20-2019
Your question is not clear at all. In first code Input arguments are always defined in the variable argc. In the second example, the parameters for the 64-bit system are enumerated. Since the transition from 32 to 64-bit broke the compatibility of the transfer in a function an indefinite number of parameters. Some parameters were passed to the function through the registers and not through the stack. Therefore, macros were invented va_list, va_start, va_end. These are all different things. Choose what you need.
This User Gave Thanks to nezabudka For This Post:
# 3  
Old 02-20-2019
main and getopt aren't variadic, they're array-based.

So one solution could be converting the variadic arguments into an array.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void argfunction(char *howmany, ...);

int main(void) {
        argfunction("abc", "atext", "btext", "ctext");
        return(0);
}

void argfunction(char *howmany, ...)
{
        int n=0;
        // Never forget the NULLs, they convert mysterious "why" errors
        //  into "oh, I forgot to assign X" errors
        char *host=NULL, *user=NULL, *pass=NULL, *port=NULL;
        int argc=0;
        char *argv[16];
        va_list ap; // IIRC ap should always be the very last variable declared in a function.
        va_start(ap, howmany);

        argv[0]=""; // just tradition, argv[0] in main() is not an argument

        // checks howmany[0], assigns argv[1].
        // checks howmany[1], assigs argv[2], etc.
        while((argc<(16-2))&&howmany[argc++]) argv[argc]=va_arg(ap, char *);

        argv[argc]=NULL;         // Also traditional that argv[argc] be NULL.

        va_end(ap);

        printf("Howmany is: %s\n", howmany);
        printf("Arguments are:\n");
        for(n=1; n<argc; n++)
                printf("\t%d\t%s\n", n, argv[n]);

        optind=1; // This is global, so reset it

        // You now have argv, argc, and optind just like main to feed getopt with.
}


Last edited by Corona688; 02-20-2019 at 05:07 PM..
This User Gave Thanks to Corona688 For This Post:
# 4  
Old 02-22-2019
I guess I didn't explain things well. I assumed using a variadic function would be the only way to get optional and required parameters. I tried to implement the code from Corona688 in my own, but could not get it to work. I did more searching and came back to example 2 on this page I had been to before:

CS 417 Documents

From that example I was able to see the flags in the switch case that could make arguments required.
Code:
$ ./basic -dp -s "more stuff" blah
./basic: missing -f option
usage: ./basic [-dmp] -f fname [-s sname] name [name ...]

Thank you for the response.
This User Gave Thanks to Azrael For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Getopt Help

Hi All, An old work friend wrote a script which I've been trying to understand how a section of it currently works and work out how i can add some command line switches which i can use later in the script to append the output depending on the command line arguements. Currently it works by... (1 Reply)
Discussion started by: mutley2202
1 Replies

2. Shell Programming and Scripting

getopt in CSH

I am struggling to understand how getopt can be used in a csh script. can anybody post a csh script using getopt. Please! (4 Replies)
Discussion started by: animesharma
4 Replies

3. HP-UX

Variadic macros compilation error HP C on HP-UX

I have a macro defined like this: #define MM7_RETURN(errorNr, ...) \ { \ if(errorNr != MM7_RS_NoError) \ { ... (1 Reply)
Discussion started by: Marzullo
1 Replies

4. Shell Programming and Scripting

Help with getopt

Hi, I want to use the getopt function to parse some arguments for a script. while getopts "i:f:r:" OPTION do case $OPTION in i) iter=$OPTARG;; f) frame=$OPTARG;; r) roi=$OPTARG;; ?) echo Usage: ...... exit 2;; esac done However, I... (5 Replies)
Discussion started by: giorgos193
5 Replies

5. Solaris

use of getopt command

Hi All, Could anyone tell me how to use getopt command.....? Thanks, Pintu (2 Replies)
Discussion started by: pintupatro
2 Replies

6. Shell Programming and Scripting

getopt help

:) Can anybody help me about how to use getopt in shell scripting. (3 Replies)
Discussion started by: darshakraut
3 Replies

7. Shell Programming and Scripting

getopt help

I m trying to use getopt This is my script, but it doesn't take argument in variable, Please help. set - - `getopt mscl: $*` if then echo "Exiting...." exit 2 fi for i in $* do case $i in -m) MAIL="$i"; shift;; -s) SCRIPT=$OPTARG; shift;; -c) COB=$OPTARG; shift;;... (2 Replies)
Discussion started by: darshakraut
2 Replies

8. Shell Programming and Scripting

getopt

#!/bin/sh set -- `getopt "abco:" "$@"` a= b= c= o= while : do case "$1" in -a) a=1;; -b) b=1;; -c) c=1;; -o) shift; o="$1";; --) break;; esac shift done shift # get rid of -- # rest of script... # e.g. ls -l $@ (6 Replies)
Discussion started by: Hitori
6 Replies

9. Shell Programming and Scripting

getopt help

scriptname i have made a script to perform so tasks and i managed to complete the tasks for all the options the problem i am facing is that i can run the scripts individually but i would like to make it such that it can accept multiple options and give me the appropriate output e.g.... (1 Reply)
Discussion started by: problems
1 Replies

10. Programming

question about getopt()

I'm using getopt() to get command line options.One the optons accepts and argument.The argument is and offset.I was wondering how can I scecify that it's argument is of the type off_t.I've something like this "offset=(off_t)optarg" and it don't work. (1 Reply)
Discussion started by: angelfly
1 Replies
Login or Register to Ask a Question