CS253: Software Development with C++

Spring 2023

Arguments

Show Lecture.Arguments as a slide show.

CS253 Arguments


The Argument Clinic

Program

Here is a program, args.cc, that displays all its arguments in curly quotes:

#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {
    cout << "argc: " << argc << '\n';
    for (int i=0; i<argc; i++)
        cout << "argv[" << i << "]: “" << argv[i] << "”\n";
}

argc & argv

#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {
    cout << "argc: " << argc << '\n';
    for (int i=0; i<argc; i++)
        cout << "argv[" << i << "]: “" << argv[i] << "”\n";
}

No arguments given

% g++ -Wall ~cs253/Examples/args.cc
% ./a.out
argc: 1
argv[0]: “./a.out”

Arguments given

% g++ -Wall ~cs253/Examples/args.cc
% ./a.out red white blue
argc: 4
argv[0]: “./a.out”
argv[1]: “red”
argv[2]: “white”
argv[3]: “blue”

Three arguments were given, but argc==4, because the program name is argv[0]. That counts for one.

Program name

The -o option to g++ names the resulting program something other than a.out:

% g++ -Wall -o war ~cs253/Examples/args.cc
% ls -l
total 20
-rwx------ 1 cs253 class 18744 Nov 21 09:07 war
% ./war famine pestilence death
argc: 4
argv[0]: “./war”
argv[1]: “famine”
argv[2]: “pestilence”
argv[3]: “death”

That’s why we use argv[0] in error messages—it’s always the name of the program.

Quoting

Normally, bash splits the argument string on whitespace. Quoting with "double quotes" or 'single quotes' protects the spaces:

% g++ -Wall ~cs253/Examples/args.cc
% ./a.out Earth "Air Fire" 'Water'
argc: 4
argv[0]: “./a.out”
argv[1]: “Earth”
argv[2]: “Air Fire”
argv[3]: “Water”

More Quoting

Backslash makes ordinary things special (\n) and makes special things ordinary (\"):

cout << "They call me \"Bonehead\".\n";
They call me "Bonehead".

Putting \ before a space prevents it from breaking arguments apart:

% g++ -Wall ~cs253/Examples/args.cc
% ./a.out Peter Flopsy\ Mopsy Cotton-tail
argc: 4
argv[0]: “./a.out”
argv[1]: “Peter”
argv[2]: “Flopsy Mopsy”
argv[3]: “Cotton-tail”

The \ prevented the following space from breaking up words. Instead, the space was treated as just another character. We call this quoting, also, even though no quote characters are involved.

Special characters

Many characters have meaning in bash: `~#$&*(){}[]\|;'"<>?. These are called special characters or metacharacters.

% g++ -Wall ~cs253/Examples/args.cc
% ./a.out >foo
% cat foo
argc: 1
argv[0]: “./a.out”

> sent the output of ./a.out to the file foo. a.out did not get an argument >foo.

% g++ -Wall ~cs253/Examples/args.cc
% ./a.out ">foo"
argc: 2
argv[0]: “./a.out”
argv[1]: “>foo”

Quoting prevented > from being treated specially.

Wildcards

% echo abcdefghijklmnopqrstuvwxyz >a-b-c
% g++ -Wall ~cs253/Examples/args.cc
% ./a.out *
argc: 3
argv[0]: “./a.out”
argv[1]: “a-b-c”
argv[2]: “a.out”
% ./a.out "*"
argc: 2
argv[0]: “./a.out”
argv[1]: “*”
% ./a.out zulu*
argc: 2
argv[0]: “./a.out”
argv[1]: “zulu*”

Redirection

bash uses <, >, and | to reroute standard input/output.

% date >now
% g++ -Wall ~cs253/Examples/args.cc
% ./a.out now
argc: 2
argv[0]: “./a.out”
argv[1]: “now”
% ./a.out <now
argc: 1
argv[0]: “./a.out”

Note the difference. In the first run, now is an argument. In the second run, bash runs ./a.out with its standard input attached to the file now, and does not pass now as an argument.

Pipe

% date >now
% g++ -Wall ~cs253/Examples/args.cc
% ./a.out <now
argc: 1
argv[0]: “./a.out”
% cat now | ./a.out
argc: 1
argv[0]: “./a.out”