By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,680 Members | 1,578 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,680 IT Pros & Developers. It's quick & easy.

argv[] comparison

P: n/a
What is the safest way to make an argv[] comparison? The code below
works.

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
string test;

if(argc>1)
test = argv[1];

if(test=="NKDT")
cout << "\nComparison is true. Have program do something.\n";
else
cout << "\nComparison is false. Have program do something else.\n";

return 0;
}

May 21 '07 #1
Share this Question
Share on Google+
28 Replies


P: n/a
* ka*****@hotmail.com:
What is the safest way to make an argv[] comparison? The code below
works.

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
string test;

if(argc>1)
test = argv[1];

if(test=="NKDT")
cout << "\nComparison is true. Have program do something.\n";
else
cout << "\nComparison is false. Have program do something else.\n";

return 0;
}
Do the following:

#include <iostream>

#include <cstddef>
#include <string>
#include <vector>
#include <stdexcept>

typedef std::vector<std::stringStringVector;

bool throwX( char const s[] ) { throw std::runtime_error( s ); }

void cppMain( StringVector const& arguments )
{
arguments.size() 1
|| throwX( "usage: myprog ARG1" );

if( arguments.at(1) == "NKDT" )
{
// Do something.
}
else
{
// Do something else.
}
}

int main( int n, char* a[] )
{
try
{
cppMain( StringVector( a, a+n ) );
return EXIT_SUCCESS;
}
catch( std::exception const& x )
{
std::cerr << "!" << x.what() << std::endl;
return EXIT_FAILURE;
}
}
--
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?
May 21 '07 #2

P: n/a
On May 21, 2:39 pm, "Alf P. Steinbach" <a...@start.nowrote:
* kafe...@hotmail.com:


What is the safest way to make an argv[] comparison? The code below
works.
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
string test;
if(argc>1)
test = argv[1];
if(test=="NKDT")
cout << "\nComparison is true. Have program do something.\n";
else
cout << "\nComparison is false. Have program do something else.\n";
return 0;
}

Do the following:
<snip>

What was wrong with the OP's solution, which appeared to be much more
concise?
May 21 '07 #3

P: n/a
* da***********@fastmail.fm:
On May 21, 2:39 pm, "Alf P. Steinbach" <a...@start.nowrote:
>* kafe...@hotmail.com:
>>>
What is the safest way to make an argv[] comparison? The code below
works.
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
string test;
if(argc>1)
test = argv[1];
if(test=="NKDT")
cout << "\nComparison is true. Have program do something.\n";
else
cout << "\nComparison is false. Have program do something else.\n";
return 0;
}
Do the following:

<snip>

What was wrong with the OP's solution, which appeared to be much more
concise?
Probably directly wrong: always indicating success for the program
execution. Also probably directly wrong: doesn't handle exceptions.
However, one might design a program so that no exception should ever
propagate up to main and if it does one wants termination for ease of
debugging, not a report and failure indication. So it depends on design
and methodology and toolchain and to some extent personal preference.
But I don't think the lack of exception handling here was intentional.

Ungood: the main code has direct access to argc and argv, when the aim
is to handle them in "the safest way" (giving access is unsafe). Also
ungood in general: "using namespace std:;". Also ungood: not using
curly braces for nested statements (just about any style guideline will
tell you to use them, always, in order to support maintenance).

Appearance of conciseness: all of the OP's code is program-specific,
whereas the code I listed is mostly boilerplate, a kind of
micro-framework for this particular kind of small student program or
professional's check-it-out program or single-use personal tool program.
For consisness one could write e.g. (doing the /same/ as the OP's code)

#include <string>
#include <iostream>
int main( int n, char* a[] )
{
using namespace std;
n 1 && std::string( a[1] ) == "NKDT"
? cout << "\nComparison is true. Something.\n"
: cout << "\nComparison is false. Something else.\n";
}

getting rid of the local variable 'test' and also the 'return 0' which
is implied (it's the default) in 'main', and just to make it extra
concise I also removed that darned 'else' which otherwise would use up a
very expensive line, and the keyword 'if' which is so much to read. I
simply don't understand why so many programmers think conciseness is a
goal. They just end up not understanding their own code.

--
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?
May 21 '07 #4

P: n/a
On May 21, 8:31 pm, "kafe...@hotmail.com" <kafe...@hotmail.comwrote:
What is the safest way to make an argv[] comparison? The code below
works.
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
string test;

if(argc>1)
test = argv[1];

if(test=="NKDT")
cout << "\nComparison is true. Have program do something.\n";
else
cout << "\nComparison is false. Have program do somethingelse.\n";
return 0;
}
It depends on context. For simply "quicky" programs, I just do
it as I did in C, something like:

if ( argc 1 && strcmp( argc[ 1 ], "NKDT" ) == 0 ) {
// ...
}

As soon as the program ceases to be trivial, however, I'll use a
library based solution which strips out the options, and exposes
the remaining arguments as a std::vector<std::string>, or
something similar. Thus, my own code would be something like:

int
main( int argc, char** argv )
{
Gabi::CommandLine& args( Gabi::CommandLine::instance() ) ;
args.parse( argc, argv ) ;
if ( args.size() 1 && args[ i ] == "NKDT" ) {
// ...
} else {
// ...
}
return Gabi::ProgramStatus::returnCode() ;
}

Such binary selections are more often handled by means of
options, however:

int
main( int argc, char** argv )
{
Gabi::BooleanOption isNKDT( "NKDT" ) ;
Gabi::CommandLine& args( Gabi::CommandLine::instance() ) ;
args.parse( argc, argv ) ;
if ( isNKDT ) {
// ...
} else {
// ...
}
return Gabi::ProgramStatus::returnCode() ;
}

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 22 '07 #5

P: n/a
ka*****@hotmail.com wrote:
What is the safest way to make an argv[] comparison? The code below
works.

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
string test;

if(argc>1)
test = argv[1];

if(test=="NKDT")
cout << "\nComparison is true. Have program do something.\n";
else
cout << "\nComparison is false. Have program do something else.\n";

return 0;
}
Use a command line parser like the one in CommmonC++ :-)

#include <cc++/common.h>

ost::CommandOptionArg NKDT_Option(
"NKDT", "p", "--NKDT is for super stuff"
);

ost::CommandOptionNoArg helparg(
"help", "?", "Print help usage"
);

int main( int argc, char ** argv )
{

CommandOptionParse * args = ost::makeCommandOptionParse(
argc, argv,
"This command is so special !"
);

if ( helparg.numSet ) {
cerr << args->printUsage();
::exit(0);
}

if ( NKDT_Option.numSet )
{
cout << "\nHave program do something.\n";
return result;
} else {
cout << "\nHave program do something else.\n";
return result;
}
}

.....

The nice thing about this is that anywhere in your code, you can add
ost::CommandOptionXXX options and they're picked up automatically. So
main does not get complicated with every possible option. The command
option parser automatically pulls together all the parameters to create
a usage.

It's a little outdated in that it was written before std::string was
working properly on most compilers so it use C style stings everywhere.
May 22 '07 #6

P: n/a
On May 21, 4:28 pm, "Alf P. Steinbach" <a...@start.nowrote:
getting rid of the local variable 'test' and also the 'return 0' which
is implied (it's the default) in 'main', and just to make it extra
concise I also removed that darned 'else' which otherwise would use up a
very expensive line, and the keyword 'if' which is so much to read.
The OP's example was nothing like that. Conciseness does not
necessarily lead to obfuscation, your strawman notwithstanding.
I simply don't understand why so many programmers think conciseness is a
goal.
Nor I why so many tend to overcomplicate simple solutions to simple
problems.
They just end up not understanding their own code.
Same thing happens with over-engineered code.

May 22 '07 #7

P: n/a
* da***********@fastmail.fm:
On May 21, 4:28 pm, "Alf P. Steinbach" <a...@start.nowrote:
>getting rid of the local variable 'test' and also the 'return 0' which
is implied (it's the default) in 'main', and just to make it extra
concise I also removed that darned 'else' which otherwise would use up a
very expensive line, and the keyword 'if' which is so much to read.

The OP's example was nothing like that. Conciseness does not
necessarily lead to obfuscation, your strawman notwithstanding.
>I simply don't understand why so many programmers think conciseness is a
goal.

Nor I why so many tend to overcomplicate simple solutions to simple
problems.
It is a "standard" solution. I think you'll find it somewhere at the
beginning of Accelerated C++. Although I don't have that book.

If you have questions about it I'll be happy to answer them.

--
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?
May 22 '07 #8

P: n/a
On Mon, 21 May 2007 20:39:14 +0200, Alf P. Steinbach wrote:
* ka*****@hotmail.com:
>What is the safest way to make an argv[] comparison? The code below
works.

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
string test;

if(argc>1)
test = argv[1];

if(test=="NKDT")
cout << "\nComparison is true. Have program do something.
\n";
> else
cout << "\nComparison is false. Have program do something
else.\n";
>>
return 0;
}

Do the following:
[snip]

You appear to assume that an exception should be thrown if the command
line does not have a particular form. I see no such requirement expressed
by the OP who does not, in fact, suggest that the "false" comparison is
in any way "exceptional".

--
Lionel B
May 22 '07 #9

P: n/a
da***********@fastmail.fm wrote:
On May 21, 4:28 pm, "Alf P. Steinbach" <a...@start.nowrote:
>getting rid of the local variable 'test' and also the 'return 0' which
is implied (it's the default) in 'main', and just to make it extra
concise I also removed that darned 'else' which otherwise would use up a
very expensive line, and the keyword 'if' which is so much to read.

The OP's example was nothing like that. Conciseness does not
necessarily lead to obfuscation, your strawman notwithstanding.
>I simply don't understand why so many programmers think conciseness is a
goal.

Nor I why so many tend to overcomplicate simple solutions to simple
problems.
>They just end up not understanding their own code.

Same thing happens with over-engineered code.
std::vector is part of the standard.
std::string is part of the standard.

What about these is complex ?

There exists a minimum complexity. employing char * is usually bad news
and is prone to far more subtle complexity that is exemplified by the
OP's question.

Alf's code does more like what you would expect.

May 22 '07 #10

P: n/a
Alf P. Steinbach wrote:
#include <iostream>

#include <cstddef>
#include <string>
#include <vector>
#include <stdexcept>

typedef std::vector<std::stringStringVector;

bool throwX( char const s[] ) { throw std::runtime_error( s ); }

void cppMain( StringVector const& arguments )
{
arguments.size() 1
|| throwX( "usage: myprog ARG1" );

if( arguments.at(1) == "NKDT" )
{
// Do something.
}
else
{
// Do something else.
}
}

int main( int n, char* a[] )
{
try
{
cppMain( StringVector( a, a+n ) );
return EXIT_SUCCESS;
}
catch( std::exception const& x )
{
std::cerr << "!" << x.what() << std::endl;
return EXIT_FAILURE;
}
}
Why such a complicated solution to such a simple problem? How about
simply:

int main(int argc, char* argv[])
{
std::vector<std::stringcmdLine(argv, argv+argc);

if(cmdLine.size() 1 && cmdLine[1] == "NKDT")
{
// Do something
}
else
{
// Do something else
}
}
May 22 '07 #11

P: n/a
On May 22, 7:57 am, Gianni Mariani <gi3nos...@mariani.wswrote:
dave_mikes...@fastmail.fm wrote:
std::vector is part of the standard.
std::string is part of the standard.

What about these is complex ?

There exists a minimum complexity. employing char * is usually bad news
and is prone to far more subtle complexity that is exemplified by the
OP's question.
Not sure what you mean here - the OP's solution creates a std::string
from argv[1]. If he only cares about argv[1], his solution seemed
fine to me re: parsing the command line.

May 22 '07 #12

P: n/a
On May 22, 7:57 am, Gianni Mariani <gi3nos...@mariani.wswrote:
dave_mikes...@fastmail.fm wrote:
std::vector is part of the standard.
std::string is part of the standard.

What about these is complex ?

There exists a minimum complexity. employing char * is usually bad news
and is prone to far more subtle complexity that is exemplified by the
OP's question.
Not sure what you mean here - the OP's solution creates a std::string
from argv[1]. If he only cares about argv[1], his solution seemed
fine to me re: parsing the command line.

May 22 '07 #13

P: n/a
* Juha Nieminen:
Alf P. Steinbach wrote:
> #include <iostream>

#include <cstddef>
#include <string>
#include <vector>
#include <stdexcept>

typedef std::vector<std::stringStringVector;

bool throwX( char const s[] ) { throw std::runtime_error( s ); }

void cppMain( StringVector const& arguments )
{
arguments.size() 1
|| throwX( "usage: myprog ARG1" );

if( arguments.at(1) == "NKDT" )
{
// Do something.
}
else
{
// Do something else.
}
}

int main( int n, char* a[] )
{
try
{
cppMain( StringVector( a, a+n ) );
return EXIT_SUCCESS;
}
catch( std::exception const& x )
{
std::cerr << "!" << x.what() << std::endl;
return EXIT_FAILURE;
}
}

Why such a complicated solution to such a simple problem? How about
simply:

int main(int argc, char* argv[])
{
std::vector<std::stringcmdLine(argv, argv+argc);

if(cmdLine.size() 1 && cmdLine[1] == "NKDT")
{
// Do something
}
else
{
// Do something else
}
}
Yours is not reusable without changes. Note that the code you put in
'main' is the code in 'cppMain' (and all code that is program-specific,
i.e. that has to be written), except that 'cppMain' is safer because it
doesn't give access to the C-style arguments and because it can safely
throw exceptions. Always think about reusing code instead of inventing
the wheel over and over with just slight details different.

--
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?
May 22 '07 #14

P: n/a
* Lionel B:
On Mon, 21 May 2007 20:39:14 +0200, Alf P. Steinbach wrote:
>* ka*****@hotmail.com:
>>What is the safest way to make an argv[] comparison? The code below
works.

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
string test;

if(argc>1)
test = argv[1];

if(test=="NKDT")
cout << "\nComparison is true. Have program do something.
\n";
>> else
cout << "\nComparison is false. Have program do something
else.\n";
>> return 0;
}
Do the following:

[snip]

You appear to assume that an exception should be thrown if the command
line does not have a particular form. I see no such requirement expressed
by the OP who does not, in fact, suggest that the "false" comparison is
in any way "exceptional".
No, using an exception is just the simple and safe way to do things in
that context.

On the other hand, I do assume that any actual program will need to deal
with exceptions; otherwise you're using C++ as just a better C.

There are more options for that than just the code shown, but if you're
going to write a little toy program it's good boilerplate code.

--
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?
May 22 '07 #15

P: n/a
On May 22, 7:57 am, Gianni Mariani <gi3nos...@mariani.wswrote:
dave_mikes...@fastmail.fm wrote:
std::vector is part of the standard.
std::string is part of the standard.

What about these is complex ?

There exists a minimum complexity. employing char * is usually bad news
and is prone to far more subtle complexity that is exemplified by the
OP's question.
Not sure what you mean here - the OP's solution creates a std::string
from argv[1]. If he only cares about argv[1], his solution seemed
fine to me re: parsing the command line.

May 22 '07 #16

P: n/a
On Tue, 22 May 2007 17:04:34 +0200, Alf P. Steinbach wrote:
* Lionel B:
>On Mon, 21 May 2007 20:39:14 +0200, Alf P. Steinbach wrote:
>>* ka*****@hotmail.com:
What is the safest way to make an argv[] comparison? The code below
works.

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
string test;

if(argc>1)
test = argv[1];

if(test=="NKDT")
cout << "\nComparison is true. Have program do something.
\n";
>>> else
cout << "\nComparison is false. Have program do something
else.\n";
>>> return 0;
}
Do the following:

[snip]

You appear to assume that an exception should be thrown if the command
line does not have a particular form. I see no such requirement
expressed by the OP who does not, in fact, suggest that the "false"
comparison is in any way "exceptional".

No, using an exception is just the simple and safe way to do things in
that context.
Well, it is *a* simple(ish) and safe way.
On the other hand, I do assume that any actual program will need to deal
with exceptions;
Beside the point... the fact remains that (as far as we can know) the
"false" branch in the OP's code may be perfectly "unexceptional". In fact
his/her action for the "false" branch was "Have program do something
else". That doesn't (to me) say "throw exception".
otherwise you're using C++ as just a better C.
A perfectly honourable use for C++ ;-)
There are more options for that than just the code shown, but if you're
going to write a little toy program it's good boilerplate code.
Sure, it's a fine idiom if deployed as the OP intended, which I'm not
convinced it was.

--
Lionel B
May 22 '07 #17

P: n/a
* Lionel B:
>
Beside the point... the fact remains that (as far as we can know) the
"false" branch in the OP's code may be perfectly "unexceptional". In fact
his/her action for the "false" branch was "Have program do something
else". That doesn't (to me) say "throw exception".
I'm not sure that the effect of the OP's code was intentional, and the
question was how to deal with argv, not how to replicate the effect of
the original code (still I posted such replication else-thread).

Anyway, it's silly and just plain argumentative to object to getting too
generally useful code.

If you'd objected that the code was too special purpose it could have
been a valid objection.

--
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?
May 22 '07 #18

P: n/a
Alf P. Steinbach wrote:
Yours is not reusable without changes.
"My" version consists basically of two (2) lines: One line which
creates the vector, and another with compares the first command-line
argument. Your requirement of "reusability" for two lines of code seems
quite odd to me. It doesn't make too much sense.

As for "without changes", that's even odder. Your solution requires
exactly as many changes to be "reusable" as mine, namely changing the
string being compared.
Note that the code you put in
'main' is the code in 'cppMain' (and all code that is program-specific,
i.e. that has to be written), except that 'cppMain' is safer because it
doesn't give access to the C-style arguments and because it can safely
throw exceptions.
Do you understand the concept of over-engineering?
Always think about reusing code instead of inventing
the wheel over and over with just slight details different.
Having to write 2 lines of code is "inventing the wheel over and
over". Right.
May 22 '07 #19

P: n/a
* Juha Nieminen:
Alf P. Steinbach wrote:
>Yours is not reusable without changes.

"My" version consists basically of two (2) lines: One line which
creates the vector, and another with compares the first command-line
argument. Your requirement of "reusability" for two lines of code seems
quite odd to me. It doesn't make too much sense.
Yes, it's true, what you're saying doesn't make sense. And the reason
that what you're saying doesn't make sense, is that you have based your
reasoning on false assumptions in order to fit a preconceived senseless
conclusion. The reusability is not for two problem-specific lines of
code: it's for argument packaging, exception handling (more generally
failure handling), main return codes, and removal of access to low-level
stuff.

And that's everything except the code between the braces in 'cppMain'.

Not that your code is much inferior, since we're talking about two
extremely trivial and short programs, but it's based on reinventing the
wheel. Except if you like spaghetti and bug-fixing, the above has to
be done for any program that does anything real. Even though we're
still talking about novice programs, toy programs, small test programs.

As for "without changes", that's even odder. Your solution requires
exactly as many changes to be "reusable" as mine, namely changing the
string being compared.
That's incorrect. And the reason it's incorrect is that you envision a
specific case of reuse where your code conceivably could be reused
mostly as-is, in order to fit your preconceived incorrect conclusion.
Out of the infinitely many programs one can make you've chosen an
extremely small set parameterized by one datum, and you incorrectly call
that reusability.

> Note that the code you put in
'main' is the code in 'cppMain' (and all code that is program-specific,
i.e. that has to be written), except that 'cppMain' is safer because it
doesn't give access to the C-style arguments and because it can safely
throw exceptions.

Do you understand the concept of over-engineering?
> Always think about reusing code instead of inventing
the wheel over and over with just slight details different.

Having to write 2 lines of code is "inventing the wheel over and
over". Right.
I'm sorry, what you're writing is not meaningful.

Nobody forces you to use save work by using that little boilerplate code.

--
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?
May 22 '07 #20

P: n/a
ka*****@hotmail.com wrote:
What is the safest way to make an argv[] comparison? The code below
works.
If you use a language with pattern matching and type inference, like OCaml
or F#, then you can just write:

let () = match Sys.argv with
| [|_; test|] when test = "NKDT" ->
printf "\nComparison is true. Have program do something.\n"
| _ ->
printf "\nComparison is false. Have program do something else.\n"

The catchall pattern handles everything else safely and simply.

--
Dr Jon D Harrop, Flying Frog Consultancy
The F#.NET Journal
http://www.ffconsultancy.com/product...ournal/?usenet
May 22 '07 #21

P: n/a
On 22 Maj, 22:11, Jon Harrop <j...@ffconsultancy.comwrote:
kafe...@hotmail.com wrote:
What is the safest way to make an argv[] comparison? The code below
works.
[snipped off-topic content]
My advice to you, Jon, is to get a life and refrain from spamming
comp.lang.c++ with off-topic content.

/Peter

May 23 '07 #22

P: n/a
On Tue, 22 May 2007 18:39:43 +0200, Alf P. Steinbach wrote:
* Lionel B:
>>
Beside the point... the fact remains that (as far as we can know) the
"false" branch in the OP's code may be perfectly "unexceptional". In
fact his/her action for the "false" branch was "Have program do
something else". That doesn't (to me) say "throw exception".

I'm not sure that the effect of the OP's code was intentional,and the
question was how to deal with argv, not how to replicate the effect of
the original code (still I posted such replication else-thread).
To be clear: your code throws when no args are supplied. Surely it is
very common indeed for a program to be validly runable with or without
args - and which will do different things accordingly. Again, I've no
reason to believe the OP either did or didn't intend this and I've no
inclination to second-guess them.
Anyway, it's silly and just plain argumentative to object to getting too
generally useful code.
That clearly wasn't my objection; this was (snipped quote restored):
>Sure, it's a fine idiom if deployed as the OP intended, which I'm not
convinced it was.
Anyway, this is all pretty trivial.

--
Lionel B
May 23 '07 #23

P: n/a
On May 22, 1:57 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
dave_mikes...@fastmail.fm wrote:
On May 21, 4:28 pm, "Alf P. Steinbach" <a...@start.nowrote:
getting rid of the local variable 'test' and also the 'return 0' which
is implied (it's the default) in 'main', and just to make it extra
concise I also removed that darned 'else' which otherwise would use upa
very expensive line, and the keyword 'if' which is so much to read.
The OP's example was nothing like that. Conciseness does not
necessarily lead to obfuscation, your strawman notwithstanding.
I simply don't understand why so many programmers think conciseness isa
goal.
Nor I why so many tend to overcomplicate simple solutions to simple
problems.
They just end up not understanding their own code.
Same thing happens with over-engineered code.
std::vector is part of the standard.
std::string is part of the standard.
What about these is complex ?
There exists a minimum complexity. employing char * is usually bad news
and is prone to far more subtle complexity that is exemplified by the
OP's question.
Alf's code does more like what you would expect.
I think part of the point of Alf's code is that significant
parts of it will eventually end up in a library. For a quicky,
just using something like:

std::vector< std::string args( argv + 1, argv + argc ) ;

is probably sufficient. But real programs have a tendancy to
grow, to acquire options, etc. And it's a lot easier to adopt
Alf's solution to these evolutions than something as primitive
as the above.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 23 '07 #24

P: n/a
* James Kanze:
On May 22, 1:57 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
>dave_mikes...@fastmail.fm wrote:
>>On May 21, 4:28 pm, "Alf P. Steinbach" <a...@start.nowrote:
>>>getting rid of the local variable 'test' and also the 'return 0' which
is implied (it's the default) in 'main', and just to make it extra
concise I also removed that darned 'else' which otherwise would use up a
very expensive line, and the keyword 'if' which is so much to read.
>>The OP's example was nothing like that. Conciseness does not
necessarily lead to obfuscation, your strawman notwithstanding.
>>>I simply don't understand why so many programmers think conciseness is a
goal.
>>Nor I why so many tend to overcomplicate simple solutions to simple
problems.
>>>They just end up not understanding their own code.
>>Same thing happens with over-engineered code.
>std::vector is part of the standard.
std::string is part of the standard.
>What about these is complex ?
>There exists a minimum complexity. employing char * is usually bad news
and is prone to far more subtle complexity that is exemplified by the
OP's question.
>Alf's code does more like what you would expect.

I think part of the point of Alf's code is that significant
parts of it will eventually end up in a library. For a quicky,
just using something like:

std::vector< std::string args( argv + 1, argv + argc ) ;

is probably sufficient. But real programs have a tendancy to
grow, to acquire options, etc. And it's a lot easier to adopt
Alf's solution to these evolutions than something as primitive
as the above.
Well yes, right on. If I weren't so lazy I'd add it as a project
template in Visual Studio, or have it as a file I could copy. But I
just type it in manucally whenever I need a small tool for something
(perhaps I'm not lazy enough -- this bears thinking about!). Thought
I should share it, and I couldn't imagine that it would generate any
debate. And as mentioned, I think similar code is given in Accelerated
C++, presumably for the same reason: a simple, reusable skeleton for a
small toy program that needs to handle main arguments.

--
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?
May 23 '07 #25

P: n/a

"Alf P. Steinbach" <al***@start.nowrote in message
news:5b*************@mid.individual.net...
Well yes, right on. If I weren't so lazy I'd add it as a project template
in Visual Studio, or have it as a file I could copy. But I just type it
in manucally whenever I need a small tool for something (perhaps I'm not
lazy enough -- this bears thinking about!). Thought I should share it,
and I couldn't imagine that it would generate any debate. And as
mentioned, I think similar code is given in Accelerated C++, presumably
for the same reason: a simple, reusable skeleton for a small toy program
that needs to handle main arguments.
Just a question about your code (which I appreciated as a good example).

Why did you use:

(1)
arguments.size() 1
|| throwX( "usage: myprog ARG1" );

and not a plain if as in

(2)
if (aruments.size() <= 1) {
throwX( "usage: myprog ARG1" );
}

I've never seen this use, but of course I can understand it (even if I
haven't found it very readable at first sight).
Is (1) written that way because you wanted the condition (arguments.size() >
1) to have the form of a precondition?

--
Marco
May 23 '07 #26

P: n/a
* *PaN!*:
"Alf P. Steinbach" <al***@start.nowrote in message
news:5b*************@mid.individual.net...
>Well yes, right on. If I weren't so lazy I'd add it as a project template
in Visual Studio, or have it as a file I could copy. But I just type it
in manucally whenever I need a small tool for something (perhaps I'm not
lazy enough -- this bears thinking about!). Thought I should share it,
and I couldn't imagine that it would generate any debate. And as
mentioned, I think similar code is given in Accelerated C++, presumably
for the same reason: a simple, reusable skeleton for a small toy program
that needs to handle main arguments.

Just a question about your code (which I appreciated as a good example).

Why did you use:

(1)
arguments.size() 1
|| throwX( "usage: myprog ARG1" );

and not a plain if as in

(2)
if (aruments.size() <= 1) {
throwX( "usage: myprog ARG1" );
}

I've never seen this use, but of course I can understand it (even if I
haven't found it very readable at first sight).
Is (1) written that way because you wanted the condition (arguments.size() >
1) to have the form of a precondition?
Yes, and it's shorter, and it's a very common convention in languages
like Perl (except instead of throwX it's usually "die"). But it's a bit
unconventional. So I would not use it in code that had to maintained by
others not familiar with the idiom.

--
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?
May 23 '07 #27

P: n/a
Alf P. Steinbach wrote:
* *PaN!*:
>"Alf P. Steinbach" <al***@start.nowrote in message
news:5b*************@mid.individual.net...
>>Well yes, right on. If I weren't so lazy I'd add it as a project
template in Visual Studio, or have it as a file I could copy. But I
just type it in manucally whenever I need a small tool for something
(perhaps I'm not lazy enough -- this bears thinking about!).
Thought I should share it, and I couldn't imagine that it would
generate any debate. And as mentioned, I think similar code is given
in Accelerated C++, presumably for the same reason: a simple,
reusable skeleton for a small toy program that needs to handle main
arguments.

Just a question about your code (which I appreciated as a good example).

Why did you use:

(1)
arguments.size() 1
|| throwX( "usage: myprog ARG1" );

and not a plain if as in

(2)
if (aruments.size() <= 1) {
throwX( "usage: myprog ARG1" );
}

I've never seen this use, but of course I can understand it (even if I
haven't found it very readable at first sight).
Is (1) written that way because you wanted the condition
(arguments.size() 1) to have the form of a precondition?

Yes, and it's shorter, and it's a very common convention in languages
like Perl (except instead of throwX it's usually "die"). But it's a bit
unconventional. So I would not use it in code that had to maintained by
others not familiar with the idiom.
I have to admit that I don't like it that much in C++. I think the if
statement is much more readable. In perl, the readability is
non-existent anyway :) Probably the statement

do_something or die "with an error";

is one of the most readable :)

Regards,

Zeppe
May 23 '07 #28

P: n/a

"Alf P. Steinbach" <al***@start.nowrote in message
news:5b*************@mid.individual.net...

[... preconditions with "cond || throw"...]
I would not use it in code that had to maintained by others not familiar
with the idiom.
Indeed, that was exactly my problem here =)
I was thinking about switching from the actual macro-based approach in a
specific project with other 3 developers, who have a not-too-deep knowledge
of C++.
It's probably a bad idea =)

Thank you,
Marco
May 24 '07 #29

This discussion thread is closed

Replies have been disabled for this discussion.