1752538 Members
5012 Online
108788 Solutions
New Discussion юеВ

language and scripting

 
SOLVED
Go to solution
Laurent Menase
Honored Contributor

Re: language and scripting

the only way I see is using getopt with the while loop I gave you just above.

char * v2;
char *allcparms[256]; /* if we suppose the max param is 256.
int indexcparms=0;
......
case 'c':
if (indexcparms==256) errflg++;
else
allcparms[indexcparms++]=optarg;
while(indexcparms<256 && (v2=argv[optind]))
{
if ( v2[0]=='-' ) break;
allcparms[indexcparms++]=v2;
optind++;
}
break;

my allcparms is your optargs.

Now there is an other way which overload the argv
case 'c':
argv[optind-1]=optarg;
params=&argv[optind-1];
while((v2=argv[optind]) && (v2[0]!='-')) optind++;

break;

but then your argv will be changed.

optarg is always a pointer in argv[optind-1] string
but depends on if the option is like
getopt("c:x") will give:
-c arg1 -> optarg=optarg[optind-1]
or
-carg1 -> optarg=optarg[optind-1]+1
-xcarg1 -> optarg=optarg[optind-1]+2

So all getopt() is based on pointing in argv to avoid any other allocations.

The only problem of my last proposition is it modifies argv[] string array, so you can't parse it again.

now If you really want dynamic allocation
it can also be made .
but there is no std api.


Dennis Handly
Acclaimed Contributor

Re: language and scripting

>that is there any standard function is there like getopt using which get my variable number of arguments using some standard variable like optarg in getopt

No, you'll have to design your own. Or take Bill's and JRF's suggestion to merge the argument components into just one. Splitting those on spaces, commas or colons is easy, you could use strtok(3).

Also, I don't think Laurent's example where he changes optind will work on Linux?

I recently tried to port a HP-UX program that used getopt(3) to Linux that allowed files and options to be in any order and I wasn't successful.

>Laurent:
extern char *optarg;
extern int optind, optopt;

You really should NOT declare these but take them from their header .
But perhaps you copied this bad code from the man page. :-)
Laurent Menase
Honored Contributor

Re: language and scripting

yes indeed you guess well , I took the skleton, without reading at it from the manpage.
here is the full example tested on
hpux & debian 5 ia64
- I fixed the test I made a little quickly on -f option.
$ ./a.out -afaa bb -c aa bb cc -o 1 2 3 4 5555 -- z t u
f= aa..bb..1
allcparms:aa
allcparms:bb
allcparms:cc
parms:1
parms:2
parms:3
parms:4
parms:5555
14 z
15 t
16 u
#include
#include
int i;
main (int argc, char *argv[])
{
int c;
int bflg, aflg=0, errflg=0;
char *t;
char *ifile,*ofile;
char *allcparms[256];
char **parms=0;
int nparms=0;
int icparms=0;
while ((c = getopt(argc, argv,
":abf:o:c:")) != -1)
switch (c) {
case 'a':
aflg++;
break;
case 'f':
ifile = optarg;
if (optind+1>argc)
errflg++;/*not enough parms with -f ( 2 parms) */
else
ofile = argv[ optind++];
break;

case 'c':
if(icparms==256)
{
errflg++; break;
}
allcparms[icparms++]=optarg;
while ( icparms<256 &&
(t=argv[optind]))
{
if (t[0] == '-' ) break;
allcparms[icparms++]=t;
optind++;
}
break;
case 'o':
argv[optind-1]=optarg;
parms=&argv[optind-1];
nparms=1;
while ((t=argv[optind]) &&
(t[0]!='-'))
{
optind++; nparms++;
}
break;

case ':':
fprintf(stderr, "Option -%c requires an argument\n", optopt);
errflg++;
break;
case '?':
fprintf(stderr, "Unrecognized option: - %c\n", optopt);
errflg++;
}
if (errflg) {
fprintf(stderr, "usage: . . . ");
exit (2);
}
printf("f=%s..%s..%d\n",ifile,ofile,aflg);
for (i=0;i printf("allcparms:%s\n",allcparms[i]);
while (nparms--)
printf("parms:%s\n",parms++[0]);
for ( ; optind < argc; optind++)
printf("%d %s\n",optind,argv[optind]);
}