I'm writing a command line utility in C to process image files. In its current state, the application can accept multiple explicit file names though argv
, but I'd like to add support for wildcards, like this:
imgprocess.exe *.png *.gif
or
./imgprocess *.png *.gif
It seems like this should be a common enough thing to be supported by C99, but I'm having a very difficult time finding a standard, cross-platform solution.
For Windows, it appears (via t开发者_运维问答his article) that linking to setargv.obj
does the trick, but that's specific to Windows and I think Visual Studio.
For Linux, it looks like readdir()
or scandir()
can get me a directory listing and I can iterate through that to match files, but I think that's just Linux.
Since wildcards are such a common thing, I feel like I'm missing some kind of simple obvious solution. Currently I'm on Linux compiling with gcc, but I would like it to compile for at least Windows and Linux.
Thank you for any advice.
On Linux-like systems at least, the shell expands the wildcard into a list of filenames. So there is no need to add this functionality!
The normal way to handle this problem in a UNIX or UNIX-like environment is to not handle it at all. That is, let the shell do the glob expansion. Your program just gets a big list of files and doesn't have to worry about looking around in the filesystem at all. A quick example program:
#include <stdio.h>
int main(int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++)
{
printf("%s\n", argv[i]);
}
return 0;
}
And a couple of sample runs (the only files in the directory are example
and example.c
):
$ ./example
$ ./example *
example
example.c
$ ./example *.c
example.c
POSIX systems do support glob
and globfree
functions (try man 3 glob
, becuase just man glob
may get you the shell documentation) which do the same thing as the shell's glob behavior.
However--as others have said--it is not really common or expected that your program will process arguments that way: the user will have to quote the arguments to get them to you from the commend line.
If you want to be really cross-platform you may want to implement this functionality yourself. Say using PCRE (the Perl Compatible Regular Expression library) as the basis since this is available on all common platforms.
精彩评论