允许程序从 Swift 中的标准输入或参数读取
Allow program to read from stdin or arguments in Swift
我正在尝试编写一个 Swift 程序
- 接受来自标准输入的单个参数或管道数据,并打印它
- 如果两者都缺失,则打印一条用法消息。
假设代码包含在main.swift
中,我们有四种情况:
swift main.swift
应该输出 "Please provide some input"
swift main.swift argument
应该输出 "argument"
echo | swift main.swift
应该输出 "Please provide some input"
echo argument | swift main.swift
应该输出 "argument"
对于复合词 echo argument1 | swift main.swift argument2
,argument2
优先。
满足 1-3 很简单:
import Foundation
var input: String? = nil
if CommandLine.arguments.count > 1 {
input = CommandLine.arguments[1]
}
guard let input = input else {
print("Please provide some input")
exit(0)
}
print(input)
但是,echo argument | swift main.swift
显然会打印用法消息,因为没有参数。添加一些代码,
import Foundation
var input: String? = nil
if CommandLine.arguments.count > 1 {
input = CommandLine.arguments[1]
} else {
while let line = readLine() {
if input == nil {
if line.isEmpty { break }
input = line
} else {
input! += "\n" + line
}
}
}
guard let input = input else {
print("Please provide some input")
exit(0)
}
print(input)
现在情况 2-4 按预期工作,但情况 1 有问题。 readLine()
导致执行暂停,等待输入。如果你在没有输入的情况下按 return,正确的消息是 returned,但我想避免手动输入空白行的必要性。
如何从 stdin 读取启用读取,同时在 stdin 为空且没有参数时不会引起暂停?
我认为问题在于 readLine()
将只是等待某种输入,即使它只是使用 ctrl-d
向其发送行尾。对于您的使用,是否可以添加一个参数来告诉程序它应该等待输入?否则,它可以假设它不应该等待任何事情?
例如:
import Foundation
func readInput () -> String? {
var input:String?
while let line = readLine() {
if input == nil {
if line.isEmpty { break }
input = line
} else {
input! += "\n" + line
}
}
return input
}
var input: String? = nil
if CommandLine.arguments.count > 1 {
input = CommandLine.arguments[1]
if (input == "-i") {
input = readInput()
}
}
guard let input = input else {
print("Please provide some input")
exit(0)
}
print("input: \(input)")
然后你最终得到这样的用法和输出:
Josh Buhler 提供了缺失的部分 — 传递一个标志以启用读取标准输入。这是我最终的、简化的完整性解决方案。
import Foundation
guard CommandLine.arguments.count > 1 else {
print("Please provide an argument, or pass - to read stdin")
exit(0)
}
var input = CommandLine.arguments[1]
if input == "-" {
input = AnyIterator { readLine() }.joined(separator: "\n")
}
// do something with input
print(input)
我正在尝试编写一个 Swift 程序
- 接受来自标准输入的单个参数或管道数据,并打印它
- 如果两者都缺失,则打印一条用法消息。
假设代码包含在main.swift
中,我们有四种情况:
swift main.swift
应该输出 "Please provide some input"swift main.swift argument
应该输出 "argument"echo | swift main.swift
应该输出 "Please provide some input"echo argument | swift main.swift
应该输出 "argument"
对于复合词 echo argument1 | swift main.swift argument2
,argument2
优先。
满足 1-3 很简单:
import Foundation
var input: String? = nil
if CommandLine.arguments.count > 1 {
input = CommandLine.arguments[1]
}
guard let input = input else {
print("Please provide some input")
exit(0)
}
print(input)
但是,echo argument | swift main.swift
显然会打印用法消息,因为没有参数。添加一些代码,
import Foundation
var input: String? = nil
if CommandLine.arguments.count > 1 {
input = CommandLine.arguments[1]
} else {
while let line = readLine() {
if input == nil {
if line.isEmpty { break }
input = line
} else {
input! += "\n" + line
}
}
}
guard let input = input else {
print("Please provide some input")
exit(0)
}
print(input)
现在情况 2-4 按预期工作,但情况 1 有问题。 readLine()
导致执行暂停,等待输入。如果你在没有输入的情况下按 return,正确的消息是 returned,但我想避免手动输入空白行的必要性。
如何从 stdin 读取启用读取,同时在 stdin 为空且没有参数时不会引起暂停?
我认为问题在于 readLine()
将只是等待某种输入,即使它只是使用 ctrl-d
向其发送行尾。对于您的使用,是否可以添加一个参数来告诉程序它应该等待输入?否则,它可以假设它不应该等待任何事情?
例如:
import Foundation
func readInput () -> String? {
var input:String?
while let line = readLine() {
if input == nil {
if line.isEmpty { break }
input = line
} else {
input! += "\n" + line
}
}
return input
}
var input: String? = nil
if CommandLine.arguments.count > 1 {
input = CommandLine.arguments[1]
if (input == "-i") {
input = readInput()
}
}
guard let input = input else {
print("Please provide some input")
exit(0)
}
print("input: \(input)")
然后你最终得到这样的用法和输出:
Josh Buhler 提供了缺失的部分 — 传递一个标志以启用读取标准输入。这是我最终的、简化的完整性解决方案。
import Foundation
guard CommandLine.arguments.count > 1 else {
print("Please provide an argument, or pass - to read stdin")
exit(0)
}
var input = CommandLine.arguments[1]
if input == "-" {
input = AnyIterator { readLine() }.joined(separator: "\n")
}
// do something with input
print(input)