windows mingw 星号 '*' 通过 argv[1] 传递给字符串

windows mingw asterisk '*' passing by argv[1] to string

我在下面写了一段代码

#include<stdio.h>

int main(int argc, char *argv[]) {
    char cmd[50]="dir";
    if (argc == 2) {
        sprintf(cmd,"dir %s",argv[1]);
    }
    if (argc == 3) {
        sprintf(cmd,"dir %s %s", argv[1], argv[2]);
    }
    printf("%s\n",cmd);
    system(cmd);
    return 0;
}

当我像下面那样执行时

我认为 *argv[] 不能传递 '*'

如何传递“*.c”之类的内容?

更新

代码

#include<stdio.h>

int main(int argc, char *argv[]) {
    char cmd[50]="dir";
    if (argc == 2) {
        sprintf(cmd,"dir %s",argv[1]);
    }
    if (argc == 3) {
        sprintf(cmd,"dir %s %s", argv[1], argv[2]);
    }
    if (argc > 3) {
        sprintf(cmd,"dir %s %s", argv[1], argv[2]);
    }
    printf("%s\n",cmd);
    system(cmd);
    return 0;
}

更改如下

什么.....@.@?

再次更新代码

#include<stdio.h>
#include<string.h>

int main(int argc, char *argv[]) {
    int i;
    char sp[2]=" ", cmd[250]="dir";
    if (argc > 1) {
        sprintf(cmd,"dir /d ");
        for (i =1 ; i < argc; i ++)  {
            strcat(cmd,sp);
            strcat(cmd,argv[i]);
        }
    }
    printf("%s\n",cmd);
    system(cmd);
    return 0;
}

看看我执行后发生了什么

有点丑....有什么好主意吗?

此问题与 C 运行时无关,但与 shell 行为有关。如果您使用 Windows CMD.EXE,* 会原封不动地传递给程序,而如果您使用 Cygwin 的 bash,则 shell 会将 * 扩展到列表文件并将此扩展作为单独的参数传递给您的程序。您可以通过使用 "*"'*'.

引用通配符来防止这种扩展

请注意,您不应使用 sprintf,而应使用 snprintf 以避免缓冲区溢出。如果您 link 到非标准 Microsoft C 库,您可能需要使用 _snprintf 代替。

编辑:CMD.EXE 似乎不会扩展通配符,但是您 link 您的程序使用的 C 运行时可能会在启动时进行扩展。看到这个问题:Gnuwin32 find.exe expands wildcard before performing search

解决方法是引用参数。

编辑礼貌地承认,恐怕接受的答案不正确。这里发生的是在 C 运行时中提供了 globbing 行为,但默认行为 因编译器而异

是的,如果您不知道发生了什么,那将是一个巨大的痛苦。更糟糕的是,如果 glob 不匹配任何文件,则不会发生 globbing。我自己也很惊讶。

Visual Studio 下,默认情况下,通配符 不会 在命令行参数中展开。您可以通过 linking with setargv.obj 或 wsetargv.obj:

启用此功能
cl example.c /link setargv.obj

在 MinGW 下,默认情况下,通配符 在命令行参数中被 扩展。为了防止这种情况,您可以 link 和 CRT_noglob.o 或者,更容易地添加 global 变量:

int _CRT_glob = 0; 

在定义 main() 或 WinMain() 的文件中您自己的源代码中。