Question

I have following program and i am passing it 2 arguments at the command line as shown below. I was expecting the argc to be 3, but it prints it as 6. why?

#include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;
void usage();

int main(int argc, char *argv[])
{
    cout << argc << endl;
    if (argc != 3)
            usage();

    string regex = argv[1];
    string searchString = argv[2];

    cout << "regex: " << regex << " . searchString: " << searchString << endl;

    return 0;
}

void usage()
{
    cout << "Usage: ./stringmatch <regex> <searchString>" << endl;
    exit(1);
}

Command line:

[jim@cola c++]$ ./stringmatch [yyyy\d\d\d]* yyyy1234
 6
 Usage: ./stringmatch <regex> <searchString>
Was it helpful?

Solution

Your shell is expanding the glob pattern [yyyy\d\d\d]* so the actual number of arguments this results in depends on the contents of the current directory!

The [yyyy\d\d\d] becomes a character class matching the characters y and d, and the * matches anything that follows, so I'm guessing your current directory has 4 files that start with y or d. To see what it expands to, use echo:

$ echo [yyyy\d\d\d]*

To make it work as intended, quote the argument:

$ ./stringmatch '[yyyy\d\d\d]*' yyyy1234

OTHER TIPS

[yyyy\d\d\d]* is expanded by the shell into multiple file names that match the pattern. Quote it to get 3.

The shell resolves your command line to

./stringmatch [yd]* yyyy1234

which gives all files starting with either y or d plus yyyy1234. So if you have 4 files starting with either y and d plus yyyy1234 plus ./stringmatch will give exactly 6.

See Filename Expansion and Pattern Matching for more information.

If you want just two arguments you must quote the first one with single or double quotes

./stringmatch '[yyyy\d\d\d]*' yyyy1234

Because your shell is expanding the arguments - wrap them in '' to prevent this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top