|
From: waltbrad on 30 Nov 2007 20:45 I'm having a dickens of a time understanding how this function does what it does. I thought I understood variable argument lists, but I've been cracking my skull trying to interpret this code and cannot. I'm reading Johnson M. Hart's "Windows System Programming". He includes this function early on in his book as a utility that needs to be compiled with other his other progam examples. The function is called "Options.c" it is used to process command line option flags: (- i, -sl, etc...). So the first program, called cat.c, will be run on the command line by entering cat [options] [files] The particular argument I used was: cat -s c:\alamo.jpg The call to the function from the program is: iFirstFile = Options (argc, argv, _T ("s"), &DashS, NULL); with _T("s") being the sole flag and $DashS containing a bool value. Now here is the function: ================ DWORD Options (int argc, LPCTSTR argv [], LPCTSTR OptStr, ...) /* argv is the command line. The options, if any, start with a '-' in argv[1], argv[2], ... OptStr is a text string containing all possible options, in one-to-one correspondence with the addresses of Boolean variables in the variable argument list (...). These flags are set if and only if the corresponding option character occurs in argv [1], argv [2], ... The return value is the argv index of the first argument beyond the options. */ { va_list pFlagList; LPBOOL pFlag; int iFlag = 0, iArg; va_start (pFlagList, OptStr); while ((pFlag = va_arg (pFlagList, LPBOOL)) != NULL && iFlag < (int)_tcslen (OptStr)) { *pFlag = FALSE; for (iArg = 1; !(*pFlag) && iArg < argc && argv [iArg] [0] == '-'; iArg++) *pFlag = _memtchr (argv [iArg], OptStr [iFlag], _tcslen (argv [iArg])) != NULL; iFlag++; } va_end (pFlagList); for (iArg = 1; iArg < argc && argv [iArg] [0] == '-'; iArg++); return iArg; } ==================== I take it that argc is still the value 3. _T("s") is OptStr. But, I'm not sure what argv(1), argv(2) is. The function seems to be expecting argv to be pBOOL, but I don't know how this jives with the for statement where it expects argv[iARG][0]=='-' So, I've tried to let the argv equal my command line entries. In that case argv[1] would be cat. There is no "-" there so the for loop would be bypassed and you would get argv[2] as "-s". But as you enter the for loop it still going to reference argv[1][0] So, I just don't get the logic employed here. The programs run okay. No problem there. But not being able to understand this program is causing me problems understanding programs that rely on this function. I hope I've expressed my confusion well enough for someone to correct me. Thanks.
From: Jim Langston on 30 Nov 2007 21:50 "waltbrad" <waltbrad(a)hotmail.com> wrote in message news:90f072ba-811c-4b6a-a641-7924a3991c1b(a)e1g2000hsh.googlegroups.com... > I'm having a dickens of a time understanding how this function does > what it does. I thought I understood variable argument lists, but > I've been cracking my skull trying to interpret this code and cannot. > > I'm reading Johnson M. Hart's "Windows System Programming". He > includes this function early on in his book as a utility that needs to > be compiled with other his other progam examples. The function is > called "Options.c" it is used to process command line option flags: (- > i, -sl, etc...). So the first program, called cat.c, will be run on > the command line by entering > > cat [options] [files] > > The particular argument I used was: > > cat -s c:\alamo.jpg Okay, when you pass arguments to a program from the command line, main will accept two parameters. a number of arguments passed, and a list of pointers to the arguments themselves. argc stands for "Argument Count" (or I think so anyway) and argv for "Argument Variables" (or so I think of them). There is always one argument, argument 0, which is the name of the program executed, although it is platform dependant. argv is a pointer to an array of pointers to the c-string arguments. argv[0] would point to something like "cat" or "/cat" or "c:/my programs/cat.exe" or whatever. If you don't need it (and you usually don't) then you shouldn't worry about this one. Now, in your case argc shoudl contain the value 3. 3 parameters, Parm 0, the name of the program. parm 1 "-s" and parm 2 "c:\alamo.jpg". If you wanted to look at the first real parm (-s) it would be argv[1] which would point to a string "-s". The first character would be argv[1][0] which would be an '-' (remember, arrays in c and c++ are 0 bound). Now with that in mind, look over the function and see if you can figure out what's going on. If you still get stuck post again. > The call to the function from the program is: > > iFirstFile = Options (argc, argv, _T ("s"), &DashS, NULL); > > with _T("s") being the sole flag and $DashS containing a bool value. > > Now here is the function: > > ================ > DWORD Options (int argc, LPCTSTR argv [], LPCTSTR OptStr, ...) > > /* argv is the command line. > The options, if any, start with a '-' in argv[1], argv[2], ... > OptStr is a text string containing all possible options, > in one-to-one correspondence with the addresses of Boolean variables > in the variable argument list (...). > These flags are set if and only if the corresponding option > character occurs in argv [1], argv [2], ... > The return value is the argv index of the first argument beyond the > options. */ > > { > va_list pFlagList; > LPBOOL pFlag; > int iFlag = 0, iArg; > > va_start (pFlagList, OptStr); > > while ((pFlag = va_arg (pFlagList, LPBOOL)) != NULL > && iFlag < (int)_tcslen (OptStr)) { > *pFlag = FALSE; > for (iArg = 1; !(*pFlag) && iArg < argc && argv [iArg] [0] == '-'; > iArg++) > *pFlag = _memtchr (argv [iArg], OptStr [iFlag], > _tcslen (argv [iArg])) != NULL; > iFlag++; > } > > va_end (pFlagList); > > for (iArg = 1; iArg < argc && argv [iArg] [0] == '-'; iArg++); > > return iArg; > } > ==================== > > I take it that argc is still the value 3. _T("s") is OptStr. But, > I'm not sure what argv(1), argv(2) is. The function seems to be > expecting argv to be pBOOL, but I don't know how this jives with the > for statement where it expects argv[iARG][0]=='-' > > So, I've tried to let the argv equal my command line entries. In that > case argv[1] would be cat. There is no "-" there so the for loop would > be bypassed and you would get argv[2] as "-s". But as you enter the > for loop it still going to reference argv[1][0] > > So, I just don't get the logic employed here. The programs run okay. > No problem there. But not being able to understand this program is > causing me problems understanding programs that rely on this > function. > > I hope I've expressed my confusion well enough for someone to correct > me. > > Thanks. > > > >
From: Alf P. Steinbach on 30 Nov 2007 22:10 * waltbrad: > I'm having a dickens of a time understanding how this function does > what it does. I thought I understood variable argument lists, but > I've been cracking my skull trying to interpret this code and cannot. > > I'm reading Johnson M. Hart's "Windows System Programming". He > includes this function early on in his book as a utility that needs to > be compiled with other his other progam examples. The function is > called "Options.c" it is used to process command line option flags: (- > i, -sl, etc...). So the first program, called cat.c, will be run on > the command line by entering > > cat [options] [files] > > The particular argument I used was: > > cat -s c:\alamo.jpg > > The call to the function from the program is: > > iFirstFile = Options (argc, argv, _T ("s"), &DashS, NULL); > > with _T("s") being the sole flag and $DashS containing a bool value. > > Now here is the function: > > ================ > DWORD Options (int argc, LPCTSTR argv [], LPCTSTR OptStr, ...) argc and argv are the arguments passed to main. > /* argv is the command line. > The options, if any, start with a '-' in argv[1], argv[2], ... > OptStr is a text string containing all possible options, > in one-to-one correspondence with the addresses of Boolean variables > in the variable argument list (...). > These flags are set if and only if the corresponding option > character occurs in argv [1], argv [2], ... > The return value is the argv index of the first argument beyond the > options. */ > > { > va_list pFlagList; > LPBOOL pFlag; > int iFlag = 0, iArg; > > va_start (pFlagList, OptStr); Sets up traversal of variable arguments, the "...". > while ((pFlag = va_arg (pFlagList, LPBOOL)) != NULL > && iFlag < (int)_tcslen (OptStr)) { Each variable argument is a LPBOOL. Address of next variable argument is stored in pFlag. If NULL no more arguments to process. As extra "precaution" the programmer checks that the corresponding options in OptStr haven't been exhausted. > *pFlag = FALSE; > for (iArg = 1; !(*pFlag) && iArg < argc && argv [iArg] [0] == '-'; > iArg++) > *pFlag = _memtchr (argv [iArg], OptStr [iFlag], > _tcslen (argv [iArg])) != NULL; > iFlag++; > } Walks through the 'main' arguments (except first), as long as they are option arguments ('-' prefix) and option not found, and checks whether any corresponds to the flag being processed in the outer while loop. > > va_end (pFlagList); Cleaning up traversal of variable arguments. > for (iArg = 1; iArg < argc && argv [iArg] [0] == '-'; iArg++); Counting option arguments. > > return iArg; > } I think it's a good idea to use C++ instead of C. typedef std::vector<std::string> StringVector; typedef std::map<char, bool> BoolOptions; void getValues( BoolOptions& options, StringVector const& args ) { typedef BoolOptions::iterator OptionsIter; for( OptionsIter it = options.begin(); it != options.end(); ++it ) { for( std::size_t i = 1; i < args.size() && args[i].substr( 0, 1 ) == "-"; ++i ) { bool const optionIsSet = (args[i].find( it->first ) != std::string::npos); if( optionIsSet ) { it->second = true; break; } } } } Cheers, & hth., - Alf -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail?
|
Pages: 1 Prev: Boost licence Next: MI5 Persecution: Browse the Website (3023) |