3

I want to enter some command line arguments at run time. Like

./program abc def ghi

argc would be 4 in this case. No problem in this. But if I do

./program abc def *

or even

./program * abc def

the variable argc gives me a value far larger than 4.

On printing the entire argv array (leaving aside the 0th argument; ./program) as strings, I am given a list where the first two elements are abc and def and the others are all file names of the files contained in the working directory.

I am trying to learn C from K&R. I was trying to make an RPN calculator where we can give expressions like ./program 2 4 *.

What is the reason for this? Or am I wrong somewhere?

tf3
  • 447
  • 1
  • 4
  • 16
  • 3
    Look up "globbing" BTW: try `/bin/echo abc def *` , instead of your program. – wildplasser Mar 25 '15 at 14:27
  • 1
    The * is probably interpreted by your shell and replaced with all the files in your current directory. – MrHug Mar 25 '15 at 14:30
  • thanks. but whats the workaround? – tf3 Mar 25 '15 at 14:30
  • This is something your OS does before passing the parameters. You should probably tag this question with the relevant OS (I'm guessing Linux). As a side note, avoid K&R, it is completely outdated, filled with errors and bad programming practice. – Lundin Mar 25 '15 at 14:30
  • @Lundin, not the OS, but the shell. You could run `bash` under cygwin and get the same behavior. – Shahbaz Mar 25 '15 at 14:32
  • @Lundin: Can you please explain why K&R is outdated, filled with errors and bad programming practice? I opened a question at http://stackoverflow.com/questions/29258883/why-is-the-kr-book-outdated-filled-with-errors-and-bad-programming-practice and it seems that at least some people disagree with your claim. – juhist Mar 25 '15 at 14:50
  • @juhist [See this](http://stackoverflow.com/questions/13159564/explain-this-implementation-of-malloc-from-the-kr-book) for example. To briefly sum up why the book is bad: 1) it is filled with bad programming practice and bad program design, 2) it is filled with bugs, errors and typos, see the book's errata which is several pages, 3) It has been outdated with the release of Amendment 1 to C90, then outdated completely with the release of C99, then outdated again with the release of C11, 4) there are countless religious fanatics encouraging the use of the book for no rational reason. – Lundin Mar 26 '15 at 07:23

4 Answers4

10

Shells have a feature called globbing, where they expand certain patterns, such as * to the matching files. If in the current directory you have the following:

file1 file2 somethingelse dir1

then calling:

any_program *

will be equivalent to:

any_program file1 file2 somethingelse dir1

Or if you do:

any_program fi*

it will be equivalent to:

any_program file1 file2

This is a feature of the shell. Your C program is well-behaved.


Since shells are different, let's assume you are using bash. To prevent bash from performing expansions, you should quote the argument. For example:

any_program "fi*"

will actually pass fi* to your program, without expanding it to file1 file2.

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
  • Yes you are right i am running bash and I tried this expression. : ./program abc def "*" and it gives argc equal to 4 alright! – tf3 Mar 25 '15 at 14:37
  • @tectonicfury, globbing is a very useful feature. You just need to learn it so you can both use it effectively and not get into problems like you have. – Shahbaz Mar 25 '15 at 14:49
  • i used linux at some point where i used to do commands like 'rm *.txt' or 'ls *.txt' so i am familiar with this behaviour but i didn't think that it would act this way even if I'm running a c program.. – tf3 Mar 25 '15 at 14:54
  • @tectonicfury, `rm` and `ls` are also just c programs ;) Anyway, so bottom line of what I'm saying is that `*` is expanded by the shell, and the application (regardless of the language) has no idea the parameters came from an expanded `*`. – Shahbaz Mar 25 '15 at 15:00
  • Thanks a ton for this info now its clear to me. perfect. theres a lot i need to learn lol. – tf3 Mar 25 '15 at 15:03
3

The commandline interpretter processes the * character as a wildcard before passing the arguments to your program, just the same as it does if you type DIR *.

The simple solution is to devise a meaningful parameter that does not get interpretted.

Evil Dog Pie
  • 2,300
  • 2
  • 23
  • 46
2

If you're using bash, start the shell with the -f switch to turn off expansion of things like *

bash -f

Ryan
  • 14,392
  • 8
  • 62
  • 102
0

You can prevent * from expanding into file names by putting it into single quotes, i.e.

./program 2 4 '*'

This way your program will receive 3 input arguments with values "2", "4" and "*" in terms of C strings.

Dmitry Grigoryev
  • 3,156
  • 1
  • 25
  • 53