从命令行程序

时间:2018-05-15 04:33:47

标签: c command-line

我正在尝试编写一些有限版本的ls w / some options。

但是,我仍然坚持以干净的方式从我的论点中解析出我的选项。

例如:

$ ls -l -t somefile anotherFile

$ ls somefile -lt anotherFile

具有相同的行为。

这给我带来两个问题:

  1. 这使得使用argc更加困难。例如,我会认为参数ls -ltls都有0个参数(除了命令的名称),但是argc将-l计为参数。
  2. 因此天真实施:

    if( argc == 1) {list all the contents of cwd}
    

    不起作用。

    是否有内置的方式来获取选项以及选项计数,还是我必须自己编写函数?

    1. 我必须考虑可以安排选项的所有不同方式,并注意不要将选项混淆为文件名或目录名。似乎最干净的解决方案是从一开始就将选项与文件参数分开。是否有惯用的方法来执行此操作/是否有标准的库调用来执行此操作?

2 个答案:

答案 0 :(得分:1)

没有内置参数解析帮助,但getopt是"标准"参数解析的方法。

对于简单的应用程序,我有时会使用以下内容:

int pos=0;
argc--;argv++;
while (argc > 0) {
  if (*argv[0]=='-') {
     switch ((*argv)[1]) {
       case 'l': //-l argument
         save_option_l(++argv);
         argc--; //we consumed one name
         break;
       //... other -options here ...
       default:
         usage("unrecognized option %s", *argv);   
     }
   }
   else {
     save_positional_argument(argv,pos++);
   }
   argv++;
   argc--;
}

在这种情况下,我需要修饰符直接跟随标志。不要像第一个例子那样支持变量使用,除非有很强的理由这样做。

答案 1 :(得分:1)

如果你有Gnu的getopt实现,它会为你完成所有这些。

Posix标准getopt在遇到第一个非选项参数时终止选项处理。这符合Posix的实用程序参数解析指南,我们中的许多人更喜欢这种行为。但是其他人喜欢混合选项和非选项的能力,这是Gnu实用程序的标准,除非你设置一个具有笨拙名称POSIXLY_CORRECT的环境变量。

与该偏好一致,Gnu getopt解析参数:

  

默认是在扫描时置换argv的内容,以便最终所有非选项都在最后。这允许以任何顺序给出选项,即使对于未编写的程序也是如此。

请注意有关置换参数的措辞。这意味着如果你从

开始
ls somefile -lt anotherFile

Gnu getopt将:

  1. 举报l
  2. 举报t
  3. 报告选项结束(-1),将optind留下值2,argv现在看起来像:

    ls -lt somefile anotherFile
    
  4. 现在您可以使用以下方法处理非选项参数:

    for (int argno = optind; argno < argc; ++argno) {
      /* Do something with argv[argno] */
    }
    

    此外,您可以告诉您使用argc-optind收到了多少非选项参数,如果argc == optind,您知道没有任何参数。

    -lt分拆为两个选项是标准Posix getopt behaviour。只要第一个选项没有参数,你就可以组合选项石灰。