如何获取原始命令行参数

时间:2013-01-04 02:43:00

标签: c++ c windows

我需要将命令行参数从A.exe传递给B.exe。如果A.exe与多个args像

A.exe -a="a" -b="b"'

我可以使用

BeginProcess("B.exe", **args!**)

启动B.exe。 如何获取原始命令行参数,如

'-a="a" -b="b"'

7 个答案:

答案 0 :(得分:9)

如果您使用的是Windows,则使用GetCommandLine获取原始命令行。

请注意,GetCommandLine还包含argv [0]。因此,在将其传递给B之前,您必须从GetCommandLine的输出中超越argv [0]。

这是一些非错误检查的代码

#include <string.h>
#include <windows.h>
#include <iostream>
#include <ctype.h>

int main(int argc, char **argv)
{
    LPTSTR cmd  = GetCommandLine();

    int l = strlen(argv[0]);

    if(cmd == strstr(cmd, argv[0]))
    {
        cmd = cmd + l;
        while(*cmd && isspace(*cmd))
            ++cmd;
    }

    std::cout<<"Command Line is : "<<cmd;

}

当我以A.exe -a="a" -b="b"运行上述程序时,我得到以下输出

A.exe -a="a" -b="b"
Command Line is : -a="a" -b="b"

答案 1 :(得分:4)

以下是基于Wine's implementation of CommandLineToArgvW跳过可执行文件名的唯一正确方法:

char *s = lpCmdline;
if (*s == '"') {
    ++s;
    while (*s)
        if (*s++ == '"')
            break;
} else {
    while (*s && *s != ' ' && *s != '\t')
        ++s;
}
/* (optionally) skip spaces preceding the first argument */
while (*s == ' ' || *s == '\t')
    s++;

答案 2 :(得分:1)

main的标准定义是

int main(int argc, char* argv[])

argv变量包含命令行参数。 argc变量表示argv数组中使用了多少条目。

答案 3 :(得分:1)

在程序开始运行之前,shell中输入的原始字符串将由shell转换为argv。除了argv之外,我从来没有听说过提供“原始”命令行的操作系统或shell。

如果用户使用引号将空格字符传递给参数,该怎么办?如果他们使用反斜杠来逃避报价中的报价怎么办?不同的shell甚至可能有不同的引用规则。

如果你有一个像argv这样的列表,你应该尝试找到一个接受它的API,而不是试图实现只是辅助实际目标的字符串处理。 Microsoft非常重视安全性,他们肯定会提供一些不需要在应用程序中添加安全漏洞的东西。

我找不到有关任何C / C ++ API BeginProcess的文档;我有点假设这是Windows,但无论如何你应该仔细检查平台的参考手册以获得替代系统调用。

答案 4 :(得分:0)

这就是我将命令行重新转换为shell args的方法。有时回到输出文件很好,以保存“使用了什么参数”以及输出。逃避是基本的,足以满足大多数情况。

我在命令(i = 0)处开始输出。如果只需要参数等,可以更改为(i = 1)

//you have to free() the result!, returns null if no args
char *arg2cmd(int argc, char** argv) {
    char *buf=NULL;
    int n = 0;
    int k, i;
    for (i=0; i <argc;++i) {
        int k=strlen(argv[i]);
        buf=( char *)realloc(buf,n+k+4);
        char *p=buf+n;
        char endq=0;
        // this is a poor mans quoting, which is good enough for anything that's not rediculous
        if (strchr(argv[i], ' ')) {
            if (!strchr(argv[i], '\'')) {
                *p++='\'';
                endq='\'';
            } else {
                *p++='\"';
                endq='\"';
            }
        }
        memcpy(p, argv[i], k);
        p+=k;
        if (i < (argc-1)) *p++=' ';
        if (endq) *p++=endq;
        *p='\0';
        n = p-buf;
    }
    return buf;
}

一个简单的cpp包装器:

std::string arg2string(int argc, char **argv) {
    char *tmp=arg2cmd(argc, argv);
    std::string ret=tmp;
    free(tmp);
    return ret;
}

答案 5 :(得分:0)

在C ++ / CLI中是这样的:

String^ cmdarg = Environment::CommandLine;

答案 6 :(得分:0)

如果您使用的是Windows,我相信正确的解决方案是调用GetCommandLine()获取完整的命令行,然后PathGetArgs(CommandLine)从头开始删除arg0(您的exe路径)。