5

Background: Some Windows command-line programs allow to use *.* in their 1st argument:

myprogram *.*

and will automatically loop on all files of the directory.

Some others don't, thus requiring a batch loop:

for %%c in ("*.*") do myprogram "%%c"

Question: Is there a standard way (defined in the C language or provided by OS?) to allow *.* or *.txt in the argument, so that it would do the processing automatically on the relevant files?

int main(int argc, char *argv[])
{
    FILE *kf;

    "for fname in argv[1]"    // pseudo code here meaning: 
                              // let's loop on all files described by the first argument
    {
        kf = fopen(fname, "rb");
        ...
    }
}

I wanted to check if a solution for this exists, before rolling my own (reinventing the wheel of wildcard expansion, using FindFirstFile, etc.)

Basj
  • 41,386
  • 99
  • 383
  • 673
  • 1
    AFAIK, the program that automatically loops over *.*, as code behind them. You can always achieve same behavior, by writing codes – P0W Oct 18 '17 at 09:47
  • 6
    There is no standard in the C language. Argument expansion (if any) is done by the shell. Typically Unix/Linux shells do the expansion, but the Windows cmd doesn't. So the Windows programs where the expansion takes place do this themselves, they receive e.g. "*.txt" in `argv[1]` and then they do the directory listing themselves and process each file found. – Jabberwocky Oct 18 '17 at 09:48
  • ... [FindFirstFile](https://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx) and friends do the job. – Jabberwocky Oct 18 '17 at 09:55
  • 1
    Which compiler do you use? The library might include a way to do this for you. – Michel de Ruiter Oct 18 '17 at 09:58
  • 2
    https://learn.microsoft.com/en-us/cpp/cpp/wildcard-expansion provides some info and a link that shows how you can do this if you're using the MS Visual C++ compiler. For MinGW-w64, [there appears to be an implementation-specific global variable `_dowildcard`](https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/crt/crtexe.c#l52) that may allow you to do this; my guess is that it defaults to 0 as the internal [`__setargv`/`__wsetargv` function in `dll_argv.c`](https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/crt/dll_argv.c) sets it to 1. –  Oct 18 '17 at 10:13
  • That said, Michael Walz is correct: there is no standard for this behavior, and some of this may change at any time as it changes the ordinary behavior of a program on Windows. You're wandering into implementation-specific territory. –  Oct 18 '17 at 10:16
  • 1
    Windows doesn't really need to provide a standardized way to do shell filename globbing, because it wasn't conceived of as a system with a strong command line. If you want to get more Unix-like shell globbing on Windows, you could work with Cygwin or Windows 10 Linux Subsystem (WSL). Although there is, as others have pointed out, no actual standards in C in this area, I suggest that there is enough commonality in behaviour that filename expansion can be relied on in Cygwin, WSL, Linux, BSD, etc. If you're writing a GUI app, you probably don't need it anyway. – Kevin Boone Oct 18 '17 at 12:47
  • https://unix.stackexchange.com/a/398464/50557 is a related answer (but focus on Unix like OSes mostly) – Basile Starynkevitch Oct 18 '17 at 15:12
  • @KevinBoone, NT can't reasonably support shell globbing anyway. The process command line is limited to 32766 characters, so shell globs that produce hundreds or thousands of files might get truncated. However, it's unnecessary for the shell to do this because NT filesystems reserve the 5 wildcard characters -- i.e. asterisk, question mark, less than (`DOS_STAR`), greater than (`DOS_QM`), and double quote (`DOS_DOT`) -- and `NtQueryDirectoryFile` (the low-level system call for listing a directory) passes the filesystem a `FileName` filter, for which it should support wildcard matching. – Eryk Sun Oct 19 '17 at 00:07
  • i.e. we want consistency between applications in how they handle globbing from the command line. In Unix the shell provides the consistent implementation, and there may be inconsistencies between shells. In Windows it's handled in the filesystem, and there may be inconsistencies between filesystems. Hopefully all filesystem implementations on Windows use common runtime library routines such as [`FsRtlIsNameInExpression`](https://msdn.microsoft.com/en-us/library/ff546850); certainly Microsoft's do. – Eryk Sun Oct 19 '17 at 00:13
  • I agree entirely. I was only pointing out that, if you want to do command-line work on Windows, you aren't necessarily constrained to use the build-it shell these days. And if you're building a GUI app, you most likely aren't all that concerned with filename expansion. – Kevin Boone Oct 19 '17 at 06:36

1 Answers1

0

No, there is no standard way to do this. Something has to process '.' inside the main function. However, there may be some libraries derived outside of the main C library body, that are doing what you need to do. Also, you may write a batch file that will loop through the set of files and call the C written application as described in Windows Batch File Looping Through Directories to Process Files?

VladP
  • 529
  • 3
  • 15