【问题标题】:Is there an implementation of "getopt" for Delphi?Delphi 是否有“getopt”的实现?
【发布时间】:2010-10-24 13:10:30
【问题描述】:

在 C/C++ 中使用 getopt() 解析命令行参数并不容易。

Delphi 有类似的东西吗?或者理想情况下,使用相同的语法?我知道 Delphi 支持 FindCmdLineSwitch 和 ParamStr(),但它们仍然需要一些额外的解析。

我想要像 C 中的 getopt() 一样工作的东西。可以轻松实现基本切换开关以及在切换后捕获值的东西。请参阅下面的一些示例 C 代码以了解我在说什么:

void print_help()
{
        printf("usage:\n") ;
        printf("\t\t-i set input file\n") ;
        printf("\t\t-o set output file\n") ;
        printf("\t\t-c set config file\n") ;
        printf("\t\t-h print this help information\n") ;
        printf("\t\t-v print version\n") ;
}
 char* input_file = NULL ;
        char *query=NULL;
          char opt_char=0;
        while ((opt_char = getopt(argc, argv, "i:q:vh")) != -1)
        {
                switch(opt_char)
                {
                        case 'h':
                                print_help();
                                exit(-1);
                                break;
                        case 'v':
                                print_version() ;
                                exit(-1) ;
                                break ;
                        case 'i':
                                input_file= optarg ;
                                break ;
                        case 'q':
                                query= optarg ;
                                break ;
                        default:
                                print_help();
                                exit(-1);
                                break;
                }
        }

【问题讨论】:

    标签: delphi parsing com


    【解决方案1】:

    有一个实现TGetOpt,号称

    为 Delphi 实现一个 getopt 变体。它几乎与 POSIX 兼容,支持长选项、必需、可选和无参数

    你可以找到它here

    【讨论】:

    • 您最好将 here 替换为 Sandkasten: useful routines for Delphi programmes | stefan.huberdoc.at 之类的东西 - 谁知道该站点可能会消失,然后 here 将无用。 ...还要明确 TGetOpt 包含在集合中
    • @Wolf:我认为这不会增加任何内容,因为即使链接断开,浏览器仍会显示链接目标并允许将其复制到剪贴板。无论如何,整个答案已经变得不适合 SO(链接到外部资源),我真的不想通过编辑将它推到首页。
    • 我明白了。另一方面,我经常看到链接目标消失但它们的内容移动了,在这些情况下,页面标题绝对有帮助。但这不是唯一的原因,你可以看看Why Your Links Should Never Say "Click Here" – Smashing Magazine
    【解决方案2】:

    没有内置 - 但你可以很容易地制作一个。这应该接近你的习惯

    TsoCommandLineParser = class
    private
      fArguments:TStringList;
    public
      constructor Create();
      destructor Destroy(); override;
    
      function GetOpt(const pArgument:string; const pDefaultValue:string = ''):string;
    end;
    
    
    constructor TsoCommandLineParser.Create();
    var
      i:Integer;
    begin
      inherited Create();
      fArguments := TStringList.Create();
      for i := 1 to ParamCount() do
      begin
        fArguments.Add(ParamStr(i));
      end;
    end;
    
    destructor TsoCommandLineParser.Destroy();
    begin
      fArguments.Free();
      inherited Destroy();
    end;
    
    function TsoCommandLineParser.GetOpt(const pArgument:string; const pDefaultValue:string = ''):string;
    var
      i:Integer;
    begin
      i := fArguments.IndexOfName(pArgument);
      if i > -1 then
      begin
        Result := fArguments.ValueFromIndex[i];
      end
      else
      begin
        Result := pDefaultValue;
      end;
    end;
    

    【讨论】:

      【解决方案3】:

      有最近开源的“Gastown Delphi 命令行解析器”(例如on Torry's)。没用过,无法评论。

      【讨论】:

      【解决方案4】:

      SysUtils 单元中的 FindCmdLineSwitch 有什么问题?

      if FindCmdLineSwitch('h',['-'],false) then
        Print_Help();
      if FindCmdLineSwitch('v',['-'],false) then
        print_Version();
      

      您必须循环通过参数来获取值,但这很简单:

      if FindCmdLineSwitch('f',['-'],false) then
        for ix := 1 to paramcount do
          if (paramStr(ix) = '-f') and (ix < paramcount) then
            begin
              if fileExists( ParamStr(ix+1) ) then
                filename := ParamStr(ix+1);
              break;
            end
      

      【讨论】:

      • Getopt 允许您将多个选项组合到一个参数中。它还可以让您确保您正在按顺序处理参数。它有特殊规定,允许看起来像选项但实际上是文件名的参数(例如在上面的示例中打开名称为“-f”的文件)。
      • 啊,但是如果有人有一个-f作为文件名,而-f是一个参数,那么它怎么知道哪个是哪个?
      • -f "-f" 请注意,您可以指定选项是否带参数。
      【解决方案5】:

      FPC RTL的getopts.pp文件是实现getopt的独立Delphi(包括Delphi2009)兼容单元:

      Free Pascal 的 Getopt 实现, 仿照 GNU getopt

      unit 在 FPC SVN 存储库中可用。

      【讨论】:

        【解决方案6】:

        请参阅此 EDN 文章 http://edn.embarcadero.com/print/40404 中描述的 TCommandParser,并可在 CodeCentral http://cc.embarcadero.com/item/27574 上下载。 TCommandParser 现在也应该包含在 Delphi 演示中。在我离开之前,我将代码免费提供给 Embarcadero,所以希望他们会在某个时候将它包含在框架中或类似的东西中。

        【讨论】:

        • 抱歉,我忘记了 - CommandParser 实际上包含 IDE 提供的 Delphi 演示。
        • 我在包含的示例@john-kaster 中找不到CommandParser。此外,自您发布答案以来,链接已断开。知道我现在在哪里可以找到您的课程吗?
        • @BigSmoke 这两个链接仍然对我有用。抱歉,它还没有在演示中。这是有关它的更多信息。 wiert.me/2015/05/13/…
        【解决方案7】:

        还有一个名为 delphi-argparse 的新解析器与此问题相关。

        【讨论】:

          【解决方案8】:

          Delphi 的基于属性的解析器可以在here 找到。

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-04-30
          • 1970-01-01
          • 2021-05-26
          • 2017-12-27
          • 1970-01-01
          • 1970-01-01
          • 2013-02-17
          相关资源
          最近更新 更多