Search

7.13 — Command line arguments

The need for command line arguments

As you learned lesson 0.4 -- introduction to development, when you compile and link your program, the compiler produces an executable file. When a program is run, execution starts at the top of the function called main(). Up to this point, we’ve declared main like this:

Notice that this version of main() takes no parameters. However, many programs need some kind of input to work with. For example, let’s say you were writing a program called Thumbnail that read in an image file, and then produced a thumbnail (a smaller version of the image). How would Thumbnail know which image to read and process? The user has to have some way of telling the program which file to open. To do this, you might take this approach:

However, there is a potential problem with this approach. Every time the program is run, the program will wait for the user to enter input. This may not be a problem if you’re manually running this program once from the command line. But it is problematic in other cases, such as when you want to run this program on many files, or have this program run by another program.

Let’s look into these cases further.

Consider the case where you want to create thumbnails for all the image files in a given directory. How would you do that? You could run this program as many times as there are images in the directory, typing out each filename by hand. However, if there were hundreds of images, this could take all day! A good solution here would be to write a program that loops through each filename in the directory, calling Thumbnail once for each file.

Now consider the case where you’re running a website, and you want to have your website create a Thumbnail every time a user uploads an image to your website. This program isn’t set up to accept input from the web, so how would the uploader enter a filename in this case? A good solution here would be to have your web server call Thumbnail automatically after upload.

In both of these cases, we really need a way for an external program to pass in the filename as input to our Thumbnail program when Thumbnail is launched, rather than having Thumbnail wait for the user to enter the filename after it has started.

Command line arguments are optional string arguments that are passed by the operating system to the program when it is launched. The program can then use them as input (or ignore them). Much like function parameters provide a way for a function to provide inputs to another function, command line arguments provide a way for people or programs to provide inputs to a program.

Passing command line arguments

Executable programs can be run on the command line by invoking them by name. For example, to run the executable file “WordCount” that is located in the root directory of the C: drive on a Windows machine, you could type:

C:\>WordCount

In order to pass command line arguments to WordCount, we simply list the command line arguments after the executable name:

C:\>WordCount Myfile.txt

Now when WordCount is executed, Myfile.txt will be provided as a command line argument. A program can have multiple command line arguments, separated by spaces:

C:\>WordCount Myfile.txt Myotherfile.txt

This also works for other command line operating systems, such as Linux (although your prompt and directory structure will undoubtedly vary).

If you are running your program from an IDE, the IDE should provide a way to enter command line arguments.

In Microsoft Visual Studio, right click on your project in the solution explorer, then choose properties. Open the “Configuration Properties” tree element, and choose “Debugging”. In the right pane, there is a line called “Command Arguments”. You can enter your command line arguments there for testing, and they will be automatically passed to your program when you run it.

In Code::Blocks, choose “Project -> Set program’s arguments”.

Using command line arguments

Now that you know how to provide command line arguments to a program, the next step is to access them from within our C++ program. To do that, we use a different form of main() than we’ve seen before. This new form of main() takes two arguments (named argc and argv by convention) as follows:

You will sometimes also see it written as:

Even though these are treated identically, we prefer the first representation because it’s intuitively easier to understand.

argc is an integer parameter containing a count of the number of arguments passed to the program (think: argc = argument count). argc will always be at least 1, because the first argument is always the name of the program itself. Each command line argument the user provides will cause argc to increase by 1.

argv is where the actual argument values are stored (think: argv = argument values, though the proper name is “argument vectors”). Although the declaration of argv looks intimidating, argv is really just an array of C-style strings. The length of this array is argc.

Let’s write a short program named “MyArgs” to print the value of all the command line parameters:

Now, when we invoke this program (MyArgs) with the command line arguments “Myfile.txt” and “100”, the output will be as follows:

There are 3 arguments:
0 C:\MyArgs
1 Myfile.txt
2 100

Argument 0 is the path and name of the current program being run. Argument 1 and 2 in this case are the two command line parameters we passed in.

Dealing with numeric arguments

Command line arguments are always passed as strings, even if the value provided is numeric in nature. To use a command line argument as a number, you must convert it from a string to a number. Unfortunately, C++ makes this a little more difficult than it should be.

The C++ way to do this follows:

When run with input “567”, this program prints:

Got integer: 567

std::stringstream works much like std::cin. In this case, we’re initializing it with the value of argv[1], so that we can use operator>> to extract the value to an integer variable (the same as we would with std::cin).

We’ll talk more about std::stringstream in a future chapter.

The OS parses command line arguments first

When you type something at the command line (or run your program from the IDE), it is the operating system’s responsibility to translate and route that request as appropriate. This not only involves running the executable, it also involves parsing any arguments to determine how they should be handled and passed to the application.

Generally, operating systems have special rules about how special characters like double quotes and backslashes are handled.

For example:

MyArgs Hello world!

prints:

There are 3 arguments:
0 C:\MyArgs
1 Hello
2 world!

Typically, strings passed in double quotes are considered to be part of the same string:

MyArgs "Hello world!"

prints:

There are 2 arguments:
0 C:\MyArgs
1 Hello world!

If you want to include a literal double quote, you have to backslash the double quote:

MyArgs \"Hello world!\"

prints:

There are 3 arguments:
0 C:\MyArgs
1 "Hello
2 world!"

Conclusion

Command line arguments provide a great way for users or other programs to pass input data into a program at startup. Consider making any input data that a program requires at startup to operate a command line parameter. If the command line isn’t passed in, you can always detect that and ask the user for input. That way, your program can operate either way.

7.14 -- Ellipsis (and why to avoid them)
Index
7.12 -- Handling errors, cerr and exit

89 comments to 7.13 — Command line arguments

  • Anon

    Hey Alex,

    Why don’t you just use the atoi function from the C standard library.

    Thanks so much for all your help.

    God bless!

  • Angmar

    Hello again, Alex.

    Would you recommend using std::stoi instead of stringstream in that particular case? stoi looks a bit simpler to me as a beginner.

    [code]#include <iostream>
    #include <string>
    using namespace std;

    int
    main(int argc, char** argv)
    {
      for (int i = 1; i < argc; i++) {
        cout << stoi(*(i + argv)) << endl;
      }
      return 0;
    }

  • Tal

    Is there way to check if the input is a float?
    I used

    But the conversion doesn’t fail if the input is 10.9 for example.

    • Alex

      As you noticed, operator>> will extract whatever it can. So if you try to extract 10.9 to an int, it will extract the 10, and leave the .9 in the input stream.

      std::stringstream doesn’t provide any way to determine if the value is a float. Of course, you could always just extract to a float value if that’s a valid choice. Alternatively, you could read your input into a std::string and then look at the string to see if it has a decimal.

  • My dear c++ Teacher,
    Please accept my many thanks for you answered my question about main() arguments and for your suggestion to read here and post my question.
    First of all I use compilers online and I do not understand what is "command line".
    I run program

    by compiler
    http://codepad.org/kfWQHi1v
    and output was
    There are 1 arguments:
    0 /t
    I run by
    https://www.tutorialspoint.com/compile_cpp_online.php
    and output was
    There are 1 arguments:
    0 main
    With regards and friendship.

    • Alex

      Once you compile your program using https://www.tutorialspoint.com/compile_cpp_online.php, you can type “main myFile.txt 100” in the green box labeled “Default Term”. This will run the program you compiled with the command line arguments you typed in.

      • My dear c++ Teacher,
        Please accept my many thanks for you answered my question and for your helpful answer. I typed that you suggest me and output is
        There are 3 arguments:
        0 main
        1 my file.txt
        2 100
        However I understand nothing but that have to learn every past lesson before learn present.
        With regards and friendship.

  • Hi, Alex my name is Ngabo, i am from in Africa
    I like so much your great tutorials.

    so, i have a question about this top <<command line arguments>>
    is it possible to give a pop up message at start up program like " # MyArgs please enter your argument? : myfile.txt"

    is my question clear ?

    • Alex

      Hello Ngabo from Africa, thanks for visiting the site!

      Once the program has started executing, it’s too late to have the user pass in command line arguments. But you are free to have your program output anything or ask the user to input anything once it is running.

      Perhaps I missed the point of your question?

  • Rohit

    Hi Alex! Got some doubts.
    1) stringstream creates a variable convert, then how can we convert the initilized value to int using conver>>myint. I mean to say how this statement works? please explain.
    2) what is the diff b/w exit(0) and exit(1)? and is there anything exit(2) or exit(3) or……?

    • Alex

      1) stringstream works like std::cin does -- except instead of getting input from the user, you can give it input. Then you use operator<< to extract the output to a variable of your choice.
      2) exit returns an error code back to the OS. 0 means “everything went okay”. A non-zero values means “something went wrong”. In most cases, this error code is ignored, but it can be useful if you have another program calling your program and that other program needs to know whether your program succeeded or not.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter