LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-31-2017, 03:57 PM   #1
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Anyone know a better means to track argc in case using getopt?


Still plugging away at this:

this app can take in more than one- rather it has to take in more than one option and argument(s) before setting image to background.
example:
Code:
appname -dcenter  <dimentions> <image> 
or
appname -dcenter  <dimentions>  -add "#AADDAA" -add "#FFF000" -gradient <int> <image>
and over a half other different ways to get it to show a image on the desktop along with color(s) displayed along with it depending on type and size of image specified to show on desktop. Using the ole'
Code:
for (i = 1; i < argc; i++)
   if(strcmp(argv[i], "-string") == 0)
          doSomeThing
.....
Now I am rewriting it using getopt. Wanting to add other features along with keeping what I already have added to this one using the old format of coding it.


so now that I am at a point of having to actually check for more than one option and at times arg to go with it. I no longer have any real Idea how to keep track of argc to parse down the line off the command line. other than adding hard numbers to the array of argv. as seen in this code.

Code:
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mhsetroot.h"
#include "getinfo.h"
#include "options.h"


    char str1[10];
    int w = 0;
    int h = 0;



void init_parse_options(int argc, char **argv){

	mh_parse_options_array(argc, argv, 0);

	}

static void mh_parse_options_array(int argc, char **argv, int finalrun){


	int opterr, optind;
	static char stropts [] = "tfFcM::d:e:";
//  no_argument  0
// required_argument 1
// optional_argument 2
static struct option lstopts[] = {

		{"fullscreen", 0,  0,  'f'},
	    {"fill",  0 ,  0, 'F'},
	    {"center", 0 ,0,'c'},
	    {"tile",0 , 0, 't'},
	    {"resize-center", 1, 0, 'd'},
	    {"resize-flip-image",1 , 0, 'e'},
	    {"color", 1, 0, 'l'},


		{0,0,0,0}
	}; // end options

	int c;
	int option_index = 0;

	while (( c = getopt_long(argc, argv, stropts,lstopts,&option_index) ) != -1) {
		switch (c) {
			case 'f':
				mode = FULLSCREEN;
				printf("orptarg  %s   stdmode %d \n", optarg, (int) mode);
				break;
			case 'F':
				mode = FILL;
				printf("orptarg  %s   stdmode %d \n", optarg, (int) mode);
				break;
			case 'c':
				mode = CENTER;
				printf("orptarg  %s   stdmode %d \n", optarg, (int) mode);
				break;
			case 't':
					printf("optarg -> %s ->argc %d - argv[argc-1] -> %s\n", optarg, argc, argv[argc-1]);
					mode = TILE;
				if ( argc > 2) {
					if (strcmp(argv[2], "v")== 0) {
						mode = TILEV;
						printf("v: orptarg  %s  tilev stdmode %d  argv[argc-1] %s\n", optarg, (int) mode, argv[2]);

					}
					else if (strcmp(argv[2],  "h") == 0) {
						mode = TILEH;
					printf("v: orptarg  %s   tileh stdmode %d  argv[argc-1] %s\n", optarg, (int) mode, argv[2]);

				}
				else if (strcmp(argv[2], "hv") == 0 ) {
						mode = TILEHV;
						printf("v: orptarg  %s   tilehv stdmode %d  argv[argc-1] %s\n", optarg, (int) mode, argv[2]);
					}

					else {
						printf("\n\nDo not know argumnet  < %s > \n", argv[2]);
						exit(1);
					}
				}
				printf("mode is %d\n", (int)mode);

					break;
				case 'd':   // need a better way to check agasint argc for more to look at and process.
				//	if(strcmp(optarg, "-g")==0 && argc > ) {
					// this way works but does but need to check argc for dimentions present else throw an error if missing  
					if(strcmp(optarg, "-g")==0) {
					strcpy (str1, argv[argc-1]);
					if (findX(str1, &w, &h) == 0 ) {
					printf("width %d height %d\n'n", w,h);
					mode = DIMG;
					printf("ModMode %d\n",(int)mode);
					printf("argc is %d - arg is %s - optarg -> %s\n",argc, argv[argc-1], optarg);
					printf("argv[argc-1]%s\n", argv[argc-1]);
					printf("argv[argc-2]%s\n",argv[argc-2]);
					}
				}
					break;
			   case 'e':    //color
					mode = DFLIPIMGD;
						printf("flipimgD mode %d\n",(int)mode);
						printf("argc %d - arg is %s - optarg -> %s\n",argc, argv[argc-1], optarg);
						break;
				case 'l':
						//needs to add better meand to look ahead for -add "#FFFFFF" -add "#FFFFFF"

					default:
						break;

		} // end switch
	} // end while
} //end function
When I get to case 't' is where it starts getting what is argc count?
but looking at where findX is called too: having to check for what is after an argument or option :

I mught even be going about this all wrong. as I am writing a line of code, compiling it, then checking it, then fixing it until I get it to work, next line, same thing, then find issues, go back and start over. rethink, get frustrated, keep going... see where it's going and now I am here asking questions again.
Code:
> ./tryMe -d -g //here no dimentions given still goes to findX function.
im in findX <---
in main
in set standard image size stdmode is: 0

> ./tryMe -d -g 300x500 //here goes to findX returns needed numbers
im in findX
width 300 height 500 <----
'nModMode 1
argc is 4 - arg is 300x500 - optarg -> -g
argv[argc-1]300x500
argv[argc-2]-g
in main
in main stdmode 1
in set standard image size stdmode is: 1
mode is 1
got me Mode is 1


> ./tryMe -d -g 300x500 -add // well I have not provided for a -add still goes to findX
im in findX <---
./tryMe: invalid option -- 'a'
in main
in set standard image size stdmode is: 0


> ./tryMe -d -g 300x500 fileName // no return of dimensions needed
im in findX <---- 
in main
in set standard image size stdmode is: 0 // wrong mode set
P.S.: all of them 'extra' messages in there some are to indicate data flow going into other c files and there (dummy) functions making sure proper data is getting sent to where it needs to be, before actually putting anything that does anything other then print the information to screen.

so I am sure one that knows got a get everything off the command line parse it get the matches that tell what to do, and any information it too needs as indicated by the option then put all of the pieces together to work.

Code:
appname -option arg --long-option arg --long-option arg -shortOption arg -shortOption arg  -shotOption arg -shortOption filename
or any other combination it can be.

the big question I think is more then not " no to work down the line picking up everything then making sure it is in order before actually setting it in motion?

Because I am using the for loop line of thought going down the line one "word" at a time where I think getopt is suppose to be dealing with this and I'm just suppose to be ???



(i might end up rewriting this post- if it is just as confusing to you and what I am trying to convey is confusing to me is, so check back if you know getopt and how it really works. )

Last edited by BW-userx; 07-31-2017 at 04:02 PM.
 
Old 07-31-2017, 04:40 PM   #2
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,263
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
That is very confusing and I am not sure I understand the exact point of what you are asking.

But kind of the whole point of getopt is that you should not have to keep track of argc - getopt keeps count in optind, all you have to do is set whatever flags and values are appropriate to the option returned as required by your application.

When getopt finds the first non-option argument (i.e. not prefixed with, or exactly '-' or '--'), it returns -1. If optind is less than argc at that point then you need to get any remaining argv arguments yourself.

In general, for most applications with complex options which may appear in any order you want to parse all the options first, then perform whatever error checks you need such as -x not compatible with -y, filename not given, etc., and issue error messages and exit if necessary. Only then would you pass control to your application code, knowing that all the arguments and options are valid.

If you find yourself counting off argc inside a loop taking its input from getopt, then you are almost always doing something wrong.
 
Old 07-31-2017, 04:46 PM   #3
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
UP date Question added:

long opt is --center
I type this and it still takes it, why? shouldn't it error out? it is not a completed option

Code:
> ./tryMe --cen
orptarg  (null)   mode 3 
in main after parse options  3
now sending to loadImage.c
in set_image_modes - mode is: 3
in Load_Image mode is : 3
 
Old 07-31-2017, 04:54 PM   #4
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,263
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
No, getopt_long will match abbreviated options as long as they are not ambiguous.

From man 3 getopt:

Code:
getopt_long() and getopt_long_only()
       The  getopt_long()  function  works like getopt() except that it also accepts long options, started with
       two dashes.  (If the program accepts only long options, then optstring should be specified as  an  empty
       string  (""),  not  NULL.)   Long option names may be abbreviated if the abbreviation is unique or is an
       exact match for some defined option.
You really should read that man page!

Last edited by astrogeek; 07-31-2017 at 04:55 PM. Reason: typo(s)
 
Old 07-31-2017, 04:57 PM   #5
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by astrogeek View Post
That is very confusing and I am not sure I understand the exact point of what you are asking.

But kind of the whole point of getopt is that you should not have to keep track of argc - getopt keeps count in optind, all you have to do is set whatever flags and values are appropriate to the option returned as required by your application.

When getopt finds the first non-option argument (i.e. not prefixed with, or exactly '-' or '--'), it returns -1. If optind is less than argc at that point then you need to get any remaining argv arguments yourself.

In general, for most applications with complex options which may appear in any order you want to parse all the options first, then perform whatever error checks you need such as -x not compatible with -y, filename not given, etc., and issue error messages and exit if necessary. Only then would you pass control to your application code, knowing that all the arguments and options are valid.

If you find yourself counting off argc inside a loop taking its input from getopt, then you are almost always doing something wrong.
yeah counting off argc I knew I was not oding this right, line of though stuck on using it -- optind is the keyword I think i was looking for to use to check stuff off of. google time on that one. thanks, and


so it'd be best to just (after I figure out the proper way to use optind) use a struct to shove all of that information off the line into it then when all of that information is gotten then go back to that struct then check all information within it first to ensure it has the proper data else throw error and information to what is missing.

along with proper form of options args if out of place catch it there first.
if everything within strut is as it should be then proceeded accordingly.

(nevertheless, somewhere in here, I think I need to break off from what I am doing and go find some code to see how they do it as well)
thanks
 
Old 07-31-2017, 05:05 PM   #6
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,263
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
Another important thing to note is that getopt permutes the order of options (i.e. argv) such that all non-option arguments end up grouped together after the option arguments and their arguments, if any.

So that, these pseudo commands would appear in similar order after getopt parsing (with suitable optstring and longarg definitions)...

Code:
mycommand -ab -v some-string another-string --long-arg yet-another -T

mycommand -abvT --longarg some-string another-string yet-another
 
Old 07-31-2017, 05:09 PM   #7
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by astrogeek View Post
No, getopt_long will match abbreviated options as long as they are not ambiguous.

From man 3 getopt:

Code:
getopt_long() and getopt_long_only()
       The  getopt_long()  function  works like getopt() except that it also accepts long options, started with
       two dashes.  (If the program accepts only long options, then optstring should be specified as  an  empty
       string  (""),  not  NULL.)   Long option names may be abbreviated if the abbreviation is unique or is an
       exact match for some defined option.
You really should read that man page!
so goof ups are ok then ... as long as they are almost. sorry trying to fast track this.
 
Old 07-31-2017, 05:18 PM   #8
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by astrogeek View Post
Another important thing to note is that getopt permutes the order of options (i.e. argv) such that all non-option arguments end up grouped together after the option arguments and their arguments, if any.

So that, these pseudo commands would appear in similar order after getopt parsing (with suitable optstring and longarg definitions)...

Code:
mycommand -ab -v some-string another-string --long-arg yet-another -T

mycommand -abvT --longarg some-string another-string yet-another
so shortOptions grouped, then long_options, if any args to any of them they just need to follow the same order the options where given in prior to setting them.

Code:
-a arg1 -b arg2 --LongOption arg3 -c -d
-abcd --Long_Option arg1 arg2 arg3
that -T I seen something about it - is that not a reserve for getopt, (I didn't dig into it).
( i keep forgetting the -- indicates long option and not more than one char )
" testing for getopt's existence (-T)." from here.
http://www.bahmanm.com/blogs/command...h-using-getopt

Last edited by BW-userx; 07-31-2017 at 05:21 PM.
 
Old 07-31-2017, 05:37 PM   #9
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
My first post is confusing because this is confusing me. Now I need to also figure out how to get only valid options if one is already set for one thing - to not only get what other different "items" that can be added to it, but to stop it from accepting an option that undermines or over rides (maybe a better word) the prior option.

example
Code:
--fullscreen  (one option to set image)
--center (another option to set image)
Code:
> ./tryMe --fullscreen -center <-- oops not --
optind 0 orptarg  (null)  mode 1 
optind 0 orptarg  (null)  mode 3 
flipimgD mode 14 < don't know where that message come from. 
argc 3 - arg is -center - optarg -> nter
in main after parse options  14
now sending to loadImage.c
in set_image_modes - mode is: 14
in SetResizeLoadImage mode is 14
with proper long options
Code:
> ./tryMe --fullscreen --center
optind 0 orptarg  (null)  mode 1 
optind 0 orptarg  (null)  mode 3 
in main after parse options  3
now sending to loadImage.c
in set_image_modes - mode is: 3
in Load_Image mode is : 3
if one does not mind me asking.
Code:
	while (( c = getopt_long(argc, argv, stropts,lstopts,&option_index) ) != -1) {
		printf("C is %d\n",c);
		switch (c) {
Code:
> ./tryMe --fullscreen --center
C is 102
optind 0 orptarg  (null)  mode 1 
C is 99
optind 0 orptarg  (null)  mode 3 
in main after parse options  3
now sending to loadImage.c
in set_image_modes - mode is: 3
in Load_Image mode is : 3
where fullscreen is mode 1 and center is mode 3
this just runs across the command line when hits option(1) it takes it down the switch matches, then sets whatever is in the case, then runs across the command line again gets the second option(2) runs down the switch again, matches case for second time sets whatever is it in, on and on it goes until no more options if last option has an arg ?

Probably has something to do with setting that flag thingy - rewrite switch time, and whatever else plus more coffee.

Last edited by BW-userx; 07-31-2017 at 05:49 PM.
 
Old 07-31-2017, 05:50 PM   #10
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,263
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
Quote:
Originally Posted by BW-userx View Post
so shortOptions grouped, then long_options, if any args to any of them they just need to follow the same order the options where given in prior to setting them.
I am not sure what you are saying here, and maybe my own example confused you, so to be more precise...

The order that option args (and their arguments) are returned by getopt are the order they are encountered in argv. Options which take an argumet will be returned with their argument value set in optarg.

Non-option arguments will be permuted to the end of the argv array. When there are no option args left (i.e. when optind=argc OR when there are only non-option args remaining after permutation) getopt will return -1.

In other words, getopt differentiates between an argument to an option, and non-option arguments.

Quote:
Originally Posted by BW-userx View Post
that -T I seen something about it - is that not a reserve for getopt, (I didn't dig into it).
( i keep forgetting the -- indicates long option and not more than one char )
" testing for getopt's existence (-T)." from here.
http://www.bahmanm.com/blogs/command...h-using-getopt
No, the -T was simply an arbitrary choice of letter for my own example. In my example none of the options take an argument, I simply wanted to show how non-option args are permuted.

The -T is not reserved for getopt, you can freely use -T in your options (shell getopt or C getopt()). You are confusing the shell invocation of getopt (man getopt) with the C function getopt (man 3 getopt)...

You really should slow down and read that man page!
 
Old 07-31-2017, 05:57 PM   #11
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by astrogeek View Post
I am not sure what you are saying here, and maybe my own example confused you, so to be more precise...

The order that option args (and their arguments) are returned by getopt are the order they are encountered in argv. Options which take an argumet will be returned with their argument value set in optarg.

Non-option arguments will be permuted to the end of the argv array. When there are no option args left (i.e. when optind=argc OR when there are only non-option args remaining after permutation) getopt will return -1.

In other words, getopt differentiates between an argument to an option, and non-option arguments.
Quote:
No, the -T was simply an arbitrary choice of letter for my own example. In my example none of the options take an argument, I simply wanted to show how non-option args are permuted.

The -T is not reserved for getopt, you can freely use -T in your options (shell getopt or C getopt()). You are confusing the shell invocation of getopt (man getopt) with the C function getopt (man 3 getopt)...

You really should slow down and read that man page!
I did - still didn't get it. and yes every time I google I get bash getopt then realize its for bash and want only C examples.

I just found out about this thing called getopts, then found out moments later it is for bash too.

basically I'm trying to absorb this information at the moment.
 
Old 08-01-2017, 02:34 PM   #12
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
well I got it working again - with just the bare minimum to set the image on desktop, now I got a do getopt for colors.

that // optional_argument 2 don't work for crap -- no wonder no one shows an example just for that one.

Last edited by BW-userx; 08-01-2017 at 02:37 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] argc and argv confusion atlantis43 Programming 4 09-28-2013 10:42 AM
gdb cannot display argc/argv? Nick_Battle Programming 3 01-12-2007 12:06 PM
how to pass argv[] & argc to functions? skie_knite007 Programming 2 05-13-2005 11:12 PM
main(int argc, char **argv) Longinus Programming 4 06-12-2004 07:22 AM
argc argv linuxanswer Programming 8 10-25-2003 07:54 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:29 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration