2

换句话说,有没有办法在一个字符串中捕获整个命令行(甚至命令行的参数部分),包括所有分隔符?

我明确地不寻找涉及连接 argv 元素的解决方案。此类解决方案假定有关分隔符或参数格式的某些内容。

例如,让我们看下面的程序:

#include <stdio.h>

int main(int argc, char** argv){
    int i;
    for (i = 0; i < argc; i++)
        puts(argv[i]);
}

如果我像这样运行它:

 Test.exe 1 2

我得到输出:

 Test.exe
 1
 2

这不是问题,但是当我像这样运行它时:

Test.exe "1" "2"

我得到完全相同的输出,这是一个问题。基本上,我试图获取作为命令行发出的逐字字符串。

4

5 回答 5

3

C 中没有内置方法可以将命令行(或参数)作为单个字符串检索,并且所有引号都完好无损,至少语言标准没有定义。部分问题是argv数组的定义,部分问题是您的 shell在将参数传递给程序之前所做的事情(例如删除引号):

5.1.2.2.1 程序启动...——
如果
的值argc大于零,则argv[0]通过 argv[argc-1]inclusive 的数组成员应包含指向字符串的指针,这些指针在程序启动之前由宿主环境赋予实现定义的值。目的是从托管环境中的其他地方向程序提供在程序启动之前确定的信息。如果主机环境不能提供大写和小写字母的字符串,则实现应确保以小写形式接收字符串。

强调我的。

可能有特定于平台的扩展可以满足您的需求,但我个人不知道。

于 2012-04-17T18:26:46.063 回答
0

您可以使用 Environment 属性之一

Environment.CommandLine
于 2012-04-17T17:59:14.043 回答
0

int main (int argc, char** argv)

argc 是参数计数,argv 是参数器。我相信它们是空间分隔的。

如果您想将它们合并到一个字符串中,可以这样做:(请原谅我,如果写得不好)。

#include <sstream>
#include <string>
// --------
std::stringstream S;
for (int i = 0; i < argc; ++i)
    S << argv[i];

std::string Str = S.str();

合并时您可能还想在它们之间添加空格,但是,我认为它没有多大用处,除了调试目的。按原样使用它们,或者放入vector<string>通常是最方便的方式。

哦,没有意识到(我总是犯这个错误)它应该是纯 C。在那种情况下,让它们保持原样。我不会删除上面的代码,以防有人在 C++ 中使用它。

于 2012-04-17T17:57:47.580 回答
0

C 和 C++ 甚至连命令行的概念都没有。该程序只是在 的参数中获取它的argv参数main。如何做到这一点取决于实施。

在 Windows 上,您可以调用GetCommandLine. 您的程序实际上在启动之前已经调用了它,main因为这是 Windows 程序首先作为填充argv数组任务的一部分所做的事情。

在 Unix 和 Linux 上,命令行在程序开始运行之前就被解析和分解。命令行参数被传递给exec函数族

如果您需要一种跨平台且可移植的方式来读取逐字命令,我建议您从文件中读取它们,而不是命令行。命令行受命令解释器(如 bash 或 cmd.exe)的处理。

于 2012-04-17T18:43:19.077 回答
0

Unix——这里的 C 显示了它的 unix 起源——有一个参数的概念,而不是命令行的概念。命令行由 shell 解析,shell 将它们拆分为参数,程序只看到参数。

在具有命令行概念的系统上,可以将命令行作为第一个参数传递并让程序解析它们。大多数 C 实现不这样做——至少在默认情况下——它们从命令行进行自己的参数拆分。

根据您的上下文,您可以:

  • 接受 C 方式是 Unix 方式,不要试图强加其他东西;
  • 重建命令行(但你必须注意引用);
  • 使用系统相关的方式来访问未解析的命令行(如果有的话)。

如果您想要可移植性,第一个可能是最好的,如果您必须遵守与您的实现为参数拆分提供的约定不同的约定,那么最后一个可能是最好的。

于 2012-04-17T18:38:13.467 回答