【问题标题】:A reliable pattern for command-line arguments命令行参数的可靠模式
【发布时间】:2012-03-13 06:01:58
【问题描述】:

我看到很多程序都使用带有标志的命令行参数,例如gcc hello.c -o hello。当然,我可以在我的应用程序中实现它:

Dim args() As String = Environment.GetCommandLineArgs()
Dim oi As Integer = Array.IndexOf("-o", args)
If oi > -1 AndAlso oi < args.Length Then
    CompileTo(args(oi + 1)) 'Or whatever
Else
    CompileTo("out.exe") 'Or whatever
End If

但它使用起来又丑又烦,容易出错,效率低下。我一直忽略的更好方法是什么?

【问题讨论】:

    标签: .net vb.net command-line-arguments


    【解决方案1】:

    请您查看Best way to parse command line arguments in C#?,有一些关于类似主题的有趣答案(C#,但这不重要)。它还显示了指向您可能想要使用的“即用型”库的链接。

    【讨论】:

    • 看起来很棒!不过,我认为这对于我的应用程序来说可能有点多。 +1
    【解决方案2】:

    在许多(大多数?)Linux 程序中,这些选项由getopt 处理。这是一个非常通用的系统,因此它可能是一个很好的起点并获得一些灵感。

    【讨论】:

      【解决方案3】:

      创建一个带有 - 名为 OptString 的文本框和文本:-in "c:\my docs\my files" +n -sort:a -xyz - 名为 wop 的文本框(错误选项的缩写) - 名为 ParseBt 的按钮 - RichTextBox 命名为 rtb(RichTextBox 的缩写)

      添加此代码并运行它:

      Public Class Form1
      Dim ListOfPossibleOptions As New Collection  
      
      Dim RejectedOptions As String   
      
      Private Sub ParseBt_Click(sender As System.Object, e As System.EventArgs) Handles ParseBt.Click
          ListOfPossibleOptions.Clear()
          ListOfPossibleOptions.Add(New OneOption("Input", " "c, True))
          ListOfPossibleOptions.Add(New OneOption("Sort", ":"c))
          ListOfPossibleOptions.Add(New OneOption("New"))
      
          ParseOptions(ListOfPossibleOptions, RejectedOptions)
      
          Dim s As String = ""
          For Each CurrOption As OneOption In ListOfPossibleOptions
              s &= CurrOption.OptionText & ": "
              If CurrOption.Present Then
                  s &= "Present option=" & CurrOption.OptionChar
                  If CurrOption.ValueReq Then
                      s &= " value=" & CurrOption.TextValue
                  End If
              Else
                  s &= "not present"
              End If
              s &= vbCrLf
          Next
          rtb.Text = s
      End Sub
      Sub ParseOptions(ListOfPossibleOptions As Collection, RejectedOptions As String)
          Dim Fnd As Boolean
          Dim OptionString As String = OptString.Text.Trim.ToUpper & " "
          Dim OptionFnd As OneOption
          RejectedOptions = ""
          While OptionString.Length() > 0
              Fnd = False
              Do While True
                  For Each CurrOption As OneOption In ListOfPossibleOptions
                      Dim ot As String = CurrOption.OptionText.ToUpper
                      For l As Integer = 1 To CurrOption.OptionText.Length
                          If l < OptionString.Length Then
                              Debug.WriteLine("|" & ot.Substring(0, l) & "|" & OptionString.Substring(1, l) & "|")
                              If ot.Substring(0, l) = OptionString.Substring(1, l) Then
                                  If OptionString.Substring(1 + l, 1) = CurrOption.Separator Then
                                      Fnd = True
                                      OptionFnd = CurrOption
                                      OptionFnd.Present = True
                                      OptionFnd.OptionChar = OptionString(0)
                                      OptionString = OptionString.Substring(l + 2)
                                      Exit Do ' found
                                  End If
                              Else
                                  Exit For ' next possible option
                              End If
                          End If
                      Next
                  Next
                  Exit Do ' not found
              Loop
              If Not Fnd Then
                  Dim i As Integer = OptionString.IndexOf(" ")
                  RejectedOptions &= OptionString.Substring(0, i) & " "
                  OptionString = OptionString.Substring(i).TrimStart
              Else
                  If OptionFnd.ValueReq Then
                      If OptionFnd.Quoted Then
                          If OptionString(0) = """" Then
                              OptionString = OptionString.Substring(1)
                              Dim i As Integer = OptionString.IndexOf("""")
                              If i > -1 Then
                                  OptionFnd.TextValue = OptionString.Substring(0, i)
                                  OptionString = OptionString.Substring(i + 1).TrimStart
                              Else ' closing quote missing
                                  i = OptionString.IndexOf(" ")
                                  OptionFnd.TextValue = """" & OptionString.Substring(0, i)
                                  OptionString = OptionString.Substring(i).TrimStart
                              End If
                          Else ' not quoted
                              Dim i As Integer = OptionString.IndexOf(" ")
                              OptionFnd.TextValue = OptionString.Substring(0, i)
                              OptionString = OptionString.Substring(i).TrimStart
                          End If
                      Else ' never quoted
                          Dim i As Integer = OptionString.IndexOf(" ")
                          OptionFnd.TextValue = OptionString.Substring(0, i)
                          OptionString = OptionString.Substring(i).TrimStart
                      End If
                  End If
              End If
          End While
          wop.Text = RejectedOptions
      End Sub
      Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
      End Sub
      End Class
      Public Class OneOption
      'input
      Friend OptionText As String ' required
      Friend Separator As Char ' if specified, CurrOption value follows the option, like : in -SORT:A
      Friend Quoted As Boolean ' value may be "q u o t e d"   
      'work
      Friend ValueReq As Boolean ' is value required (as seperator was given in NEW)?
      'output 
      Friend Present As Boolean ' option present
      Friend OptionChar As Char ' options was preceeded by + - / whatever
      Friend TextValue As String ' the value following the option
      Sub New(pOptionText As String) ' option without a value, a switch
          OptionText = pOptionText
          reset()
      End Sub
      Sub New(pOptionText As String, pSeparator As Char) ' option with a value, the separator between option and value has to be specified
          OptionText = pOptionText
          reset()
          Separator = pSeparator
          ValueReq = True
          Quoted = False
      End Sub
      Sub New(pOptionText As String, pSeparator As Char, pQuoted As Boolean) ' option with a possibly "quoted value", the separator between option and value has to be specified
          OptionText = pOptionText
          reset()
          Separator = pSeparator
          ValueReq = True
          Quoted = pQuoted
      End Sub
      Sub reset()
          Separator = " "c
          Quoted = False
          Present = False
          ValueReq = False
      End Sub
      End Class
      

      【讨论】:

      • 我在控制台应用程序中,Windows 窗体演示有点……无关紧要。我想我理解你的代码,但它有点大而且写得不是很好......(例如,不要使用Do While True...Loop)。
      • 在拒绝之前先看看解决方案!例程 ParseOptions 在控制台环境中执行您想要的所有操作,该表单仅用于运行和演示它。祝你下次好运。
      • 嗯,是的——但你不需要把它弄乱就可以让它工作。然后是过于复杂的字符串搜索算法。我已经有了答案。
      猜你喜欢
      • 2011-08-11
      • 1970-01-01
      • 2011-06-27
      • 2017-04-04
      • 2012-10-06
      • 1970-01-01
      • 2015-07-05
      • 2020-11-15
      相关资源
      最近更新 更多