如何在Swift 3中使用带有命令行参数的getopt?

时间:2016-12-23 17:54:14

标签: swift command-line swift3

我试图在Swift 3中使用带有命令行参数的getopt。我来自Michele Dall'Agata's nice stackoverflow contribution

let pattern = "abc:"
var buffer = Array( pattern.utf8 ).map { Int8($0) }

当我使用此代码时:

let option = Int( getopt( CommandLine.argc, CommandLine.arguments, buffer ) )

我收到此错误:

  

无法转换类型' [String]'的值预期的参数类型   '&UnsafePointer LT; UnsafeMutablePointer< INT8>?>!'

用于CommandLine.arguments,我尝试将其用作argv。有谁知道getopt的第二个参数的正确语法?提前谢谢!

2 个答案:

答案 0 :(得分:6)

@Hamish已经回答了这个问题并解释了如何在Swift中将CommandLine.unsafeArgv传递给getopt()(及其原因)。

这是一个完整的自包含示例,如何典型的getopt 循环可以在Swift 3中实现:

var aFlag = false
var bFlag = false
var cValue: String?

while case let option = getopt(CommandLine.argc, CommandLine.unsafeArgv, "abc:"), option != -1 {
    switch UnicodeScalar(CUnsignedChar(option)) {
    case "a":
        aFlag = true
    case "b":
        bFlag = true
    case "c":
        cValue = String(cString: optarg)
    default:
        fatalError("Unknown option")
    }
}

print(aFlag, bFlag, cValue ?? "?")

说明:

  • 您可以将Swift字符串(此处:"abc:")直接传递给C 函数期望一个(常量)C字符串,编译器会自动执行 生成一个临时的UTF-8表示。
  • getopt()返回-1(如果参数列表已用尽)或unsigned char转换为int。因此它是安全的 将返回值转换为CUnsignedChar(在Swift中为UInt8)。
  • while使用(滥用?)模式匹配加一个额外的 布尔条件实现典型的C模式

    while ((option = getopt(argc, argv, "abc:")) != -1) { ... }
    

    在斯威夫特。

答案 1 :(得分:5)

CommandLine.arguments为您提供了一个友好的Swift [String]传递的参数 - 但是您希望将参数直接发送回C.因此您只需使用CommandLine.unsafeArgv代替,它将为您提供传递给您的程序的argv的实际原始值。

let option = Int( getopt( CommandLine.argc, CommandLine.unsafeArgv, buffer ) )