处理C / C ++中的命令行标志

时间:2013-02-06 20:16:05

标签: c unix command-line-arguments

我正在寻找关于标志是什么的非常简单的解释/教程。我知道标志工作表明命令该做什么。例如:

rm -Rf test

我知道rm命令将删除测试文件夹,并且-Rf标志将强制命令不仅删除文件夹而且删除其中的文件。

但是,标志读取/编译在哪里?处理旗帜的是什么?例如,我可以编写自己的C / C ++程序并指定不同的标志,以便程序执行不同的操作吗?我希望我提出正确的问题。如果没有,请告诉我。

7 个答案:

答案 0 :(得分:12)

在C级别,程序的命令行参数显示在main函数的参数中。例如,如果您编译此程序:

#include <stdio.h>
int main(int argc, char **argv)
{
    int i;
    for (i = 0; i < argc; i++)
        printf("argv[%d] = %s\n", i, argv[i]);
    return 0;
 }

并使用与示例相同的参数调用它&#39; rm&#39;命令,你得到这个:

$ ./a.out -Rf test
argv[0] = ./a.out
argv[1] = -Rf
argv[2] = test

如您所见,argv中的第一个条目是程序本身的名称,其余的数组条目是命令行参数。

操作系统完全不关心参数是什么;由您的程序来解释它们。但是,有关它们如何工作的惯例,其中以下是最重要的:

  • 参数分为选项非选项。选项以破折号开头,非选项不是。
  • 顾名思义,选项应该是可选。如果你的程序需要一些命令行参数来做任何有用的事情,那些参数应该是非选项(即它们以破折号开头)。
  • 选项可以进一步划分为选项,这些选项是单个短划线后跟一个字母(-r-f)和 long 选项,它们是两个短划线,后跟一个或多个以短划线分隔的单词(--recursive--frobnicate-the-gourds)。只要没有一个参数(参见下文),短选项可以一起组成一个参数(-rf)。
  • 选项本身可以带参数。
    • short 选项-x的参数是argv条目的剩余部分,或者如果该条目中没有其他文本,那么下一个{{ 1}}条目是否以破折号开头。
    • long 选项的参数设置为等号:argv
  • 如果可能的话,不同选项(带有参数)的相对排序应该没有可观察到的效果。
  • 特殊选项--output=outputfile.txt表示&#34;不要在命令行上的这一点之后处理任何内容作为选项,即使它看起来像一个。&#34;例如,您可以删除名为&#39; --&#39;的文件。输入-f
  • 特殊选项rm -- -f表示&#34;阅读标准输入&#34;。
  • 按惯例保留了一些短的选项字母:最重要的是
    • - = be verbose
    • -v =安静
    • -q =打印一些帮助文字
    • -h file =输出到文件
    • -o =强制(不要提示确认危险行为,只需这样做)

有许多库可以帮助您解析命令行参数。最便携,但也是最有限的是getopt,它现在在大多数系统的C库中内置。我建议您阅读GNU argp的所有文档,即使您不想使用该特定文档,因为它会进一步教育您遵守约定。

还值得一提的是,在调用程序之前,通配符扩展(-f)已经完成。如果您将上述示例程序作为rm -rf *运行在仅包含二进制文件及其源代码的目录中,您将获得

./a.out *

答案 1 :(得分:8)

这个简单的程序应该演示传递给程序的参数(包括程序名本身。)

解析,解释和使用这些参数取决于程序员(您),尽管有可用的库可供帮助。

int main(int argc, char* argv[])
{
    int i;
    for(i=0; i<argc; ++i)
    {   printf("Argument %d : %s\n", i, argv[i]);
    }
    return 0;
}

如果您将此程序编译为a.out,并将其运行为:

prompt$>  ./a.out ParamOne ParamTwo -rf x.c

你应该看到输出:

Argument 0 : a.out
Argument 1 : ParamOne
Argument 2 : ParamTwo
Argument 3 : -rf
Argument 4 : x.c

答案 2 :(得分:4)

实际上你可以编写自己的C ++程序,它接受这样的命令行参数:

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

变量argc将包含参数的数量,而char *将包含参数本身。

您可以像这样调度参数:

for (int i = 1; i < argc; i++)
{  
    if (i + 1 != argc)
    {
        if (strcmp(argv[i], "-filename") == 0) // This is your parameter name
        {                 
            char* filename = argv[i + 1];    // The next value in the array is your value
            i++;    // Move to the next flag
        }
    }
}

答案 3 :(得分:2)

在您自己的C程序中,您可以以任何您认为合适的方式处理命令行选项。 C中的命令行参数作为字符串以main(int argc,char * argv [])方法的参数形式出现。

如果您希望以类似于大多数UNIX命令的方式处理命令行参数,那么您可能正在寻找的功能是getopt()

祝你好运!

答案 4 :(得分:0)

最简单的方法就是这样写main()

  

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

然后在主决定命令行参数或“标志”会发生什么。你在argv中找到它们,它们的编号是argc。

答案 5 :(得分:0)

flags是传递到程序主入口点的参数。例如,在C ++程序中,您可以拥有

int main(int arc, char* argv[]){
return 0;
}

你的arc是传入的参数的数量,指针给你实际的参数列表。所以

rm -Rf test

argc将为3,argv数组将包含您的参数。注意argc&gt; = 1,因为程序名称本身计数(rm)。 -RF是你的第二个参数,测试是你的第三个。

因此,无论何时在unix中键入命令,您实际上都在执行程序并传递它们所操作的参数。

如果你对unix操作系统真的很感兴趣,你应该查找它们以及它们是如何工作的。这对于新手来说可能会让人感到困惑,所以只有当你真的对操作系统感兴趣以及如何执行程序时才会感到困惑。

答案 6 :(得分:0)

GNU libc很可能在您的系统上可用,它有一个名为getopt的库,可用于以合理的方式解析选项。有一些示例可以帮助您开始下面链接的文档。

http://www.gnu.org/software/libc/manual/html_node/Getopt.html#Getopt