C++ Command line parsing

I am new to programing. I am sure I am missing something simple. I just want take my switch and check if it's used or not. However, the else statement keeps being used. What am I missing?

1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main(int argc, const char **argv)
{
        if (*argv == "-t")
                std::cout<<"This is just a test!\n";
        else
                std::cout<<"Unknown command.\n";
return 0;
}
(1) This -> *argv == "-t" doesn't compare strings, it compares pointers (i.e. memory addresses).

(2) *argv points to the first argument, which is the command used to start the program. What you want is the second argument, *(argv+1)

Try this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cstring>

//...

    if (argc!=2)
    {
        std::cout << "Invalid arguments..." << endl;
        return 1;
    }

    if ( strcmp( *(argv+1), "-t" )==0 )
        std::cout<<"This is just a test!" << endl;
    else
        std::cout<<"Unknown command" << endl;

//... 

Info on strcmp -> http://cplusplus.com/reference/clibrary/cstring/strcmp/

Maybe you also want to take a look at this -> http://cplusplus.com/forum/beginner/26251/#msg140026
You cannot compare C strings (i.e. null-terminated char arrays) using operator==.
So just convert the argument into a real string beforehand:

1
2
std::string arg=argv[1];
if (arg=="-t")...


This requires the <string> header to be included.
Also note that the first argument is the program name - so the actual argument you're looking for is the second entry in argv.
Athar wrote:
So just convert the argument into a real string beforehand

+1
That worked. However, when I didn't use a switch I got an error. So I modified it a tad so it didn't throw an error. However, it's not liking my while statement. Since Null is not making it happy what else can I use?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

int main(int argc, const char **argv)
{
        std::cout<<"Test of running command line parsing.\n\n";

        std::string arg=argv[1];

        while (arg != NULL)
        {
                if(arg == "-h")
                std::cout<<"This is a demo help file.\n";
        else
                std::cout<<"Unknown command.\n";
        }
return 0;
}

You can use argc - it contains the number of elements in argv.
Ok, it complies clean. But I'm getting the following error message when I don't use a switch.....

1
2
3
terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_S_construct NULL not valid
Aborted (core dumped)


This is what the code looks like currently....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

int main(int argc, const char **argv)
{
        std::cout<<"Test of running command line parsing.\n\n";

        if (argc != 0)
        {
                std::string arg=argv[1];
                if(arg == "-h")
                        std::cout<<"This is a demo help file.\n";
                else
                        std::cout<<"Unknown command.\n";
        }
return 0;
}


How do i get it so that it's quiet if I choose not to use a switch?
Turn this -> if (argc != 0) into this -> if (argc >= 2)
That worked well...thanks.
I'm feeling generous, so here is a way to implement a decent help message, and a few other things:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

/* Use a function to print the full help message
   Pass the arguments to it so you can use the program name, etc... */
void Help(int argc, const char **argv) {
    // std::cout is capable of quasi-multi-line statements, like so:
    std::cout << "Usage: " << argv[0] << "[options]\n"
        "Test of command-line argument parsing\n"
        "\nOptions:\n"
        "-h\tPrint this message and exit"
        "\n";
}

int main(int argc, const char **argv) {
    std::cout << "CommandLine Argument Parsing Test\n\n";
    if (argc > 1) {
        std::string arg1 = argv[1];
        if (arg1 == "-h")
            Help(argc, argv); // Print Usage & Help info
            return 0; // return to terminal after help msg, 0 for no errors
        else {
            // Use the error stream for error messages when possible...
            std::cerr << "Error: Invalid switch '" << argv[1] << "'\n";
            /* Tell the user exactly what went wrong and how to fix it ...
               i.e. how to use the program correctly. */
            Help(argc, argv);
            return 1; // Return to terminal with error status 1 after an error
        }
    }
    return 0; // return 0 for no errors
}
Last edited on
Thank you. i will study this.
Topic archived. No new replies allowed.