10

I wrote a code which has to display main parameters, but when I compiled it and typed in "*" program shows my file structure. Command in cmd looks like this: program.exe 1 2 3 *

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const* argv[]) {
    for (int i=0; i<argc; i++) printf("%s\n", argv[i]);
    return 0;
}

The result is:

program
1
2
3
program.c
program.exe
10-03-20
11-02-20

And my question: Is it possible to force program to print "*" instead of listing files.

stasio14
  • 117
  • 1
  • 6
  • 5
    The `*` gets interpreted by the shell, not the program itself. Use `\*` or `"*"` to pass the * to the program. – mch Mar 31 '20 at 09:22
  • 5
    The problem is that `*` is converted to `"file1 file2 ..."` by your shell. **There is nothing wrong with your C program** (though including `` is not necessary). To prevent the shell to convert the *star* use quotes: `program.exe 1 2 3 "*"` – pmg Mar 31 '20 at 09:23
  • Not related to the question, but strictly speaking, `char const* argv[]` is not correct. You may not invent forms of main() by yourself, only the compiler may do that. `argv` is actually read/write memory, even though writing to it is often not the best idea. – Lundin Mar 31 '20 at 09:45
  • I tried `"*"` but I gives the same. I also tried `\*` but this gives `\$Recycle.Bin` – stasio14 Mar 31 '20 at 09:47
  • Hmmm... I can't test Windows' `cmd.exe`, but try `program.exe 1 2 3 '*'`. Also, maybe it can help by itself with `cmd.exe /?` – pmg Mar 31 '20 at 09:57
  • 2
    The Windows cmd shell doesn't perform wildcard expansion. Either it's not being run from the cmd shell, or the compiler is inserting logic to emulate the expansion the shell would do – ikegami Mar 31 '20 at 10:10
  • @stasio14, What shell are you using? What compiler are you using? – ikegami Mar 31 '20 at 10:10
  • @ikegami I'm using MinGW compiler and cmd shell – stasio14 Mar 31 '20 at 10:11

1 Answers1

7

mingw causes the program to perform wildcard expansion of the parameters. Add the following to your program to disable this behaviour:

int _CRT_glob = 0;

In the unix world, the shell is expected to perform wildcard expansion.

$ perl -le'print for @ARGV' *
a
b

In the Windows world, wildcard expansion is left to the application.

>perl -le"print for @ARGV" *
*

That makes writing portable programs tricky. Since mingw is often used to compile programs that weren't written with Windows in mind, its C runtime library performs wildcard expansion of the parameters automatically.

a.c:

#include <stdio.h>

int main(int argc, char const* argv[]) {
    for (int i=0; i<argc; i++)
        printf("%s\n", argv[i]);

    return 0;
}
>gcc -Wall -Wextra -pedantic-errors a.c -o a.exe & a *
a
a.c
a.exe

But, mingw provides an out. Adding the following to your program disables this behaviour:

int _CRT_glob = 0; 

a.c:

#include <stdio.h>

int _CRT_glob = 0; 

int main(int argc, char const* argv[]) {
    for (int i=0; i<argc; i++)
        printf("%s\n", argv[i]);

    return 0;
}
>gcc -Wall -Wextra -pedantic-errors a.c -o a.exe & a *
a
*
ikegami
  • 367,544
  • 15
  • 269
  • 518