我正在尝试获取新Apple编程语言Swift的命令行应用程序的键盘输入。
我扫描过这些文档无济于事。
import Foundation
println("What is your name?")
???
有什么想法吗?
答案 0 :(得分:124)
答案 1 :(得分:59)
我设法解决了这个问题而没有进入C:
我的解决方案如下:
func input() -> String {
var keyboard = NSFileHandle.fileHandleWithStandardInput()
var inputData = keyboard.availableData
return NSString(data: inputData, encoding:NSUTF8StringEncoding)!
}
更新版本的Xcode需要一个明确的类型转换(适用于Xcode 6.4):
func input() -> String {
var keyboard = NSFileHandle.fileHandleWithStandardInput()
var inputData = keyboard.availableData
return NSString(data: inputData, encoding:NSUTF8StringEncoding)! as String
}
答案 2 :(得分:13)
实际上并不那么容易,您必须与C API进行交互。除scanf
之外别无选择。我构建了一个小例子:
<强> main.swift 强>
import Foundation
var output: CInt = 0
getInput(&output)
println(output)
的 UserInput.c 强>
#include <stdio.h>
void getInput(int *output) {
scanf("%i", output);
}
的 cliinput-桥接-Header.h 强>
void getInput(int *output);
答案 3 :(得分:6)
编辑自Swift 2.2起,标准库包含readLine
。我还会注意到Swift切换到降价文档评论。留下我对历史背景的原始答案。
为了完整起见,这是我一直在使用的readln
的Swift实现。它有一个可选参数,用于指示要读取的最大字节数(可能是也可能不是字符串的长度)。
这也证明了正确使用swiftdoc注释 - Swift将生成一个&lt; project&gt; .swiftdoc文件,Xcode将使用它。
///reads a line from standard input
///
///:param: max specifies the number of bytes to read
///
///:returns: the string, or nil if an error was encountered trying to read Stdin
public func readln(max:Int = 8192) -> String? {
assert(max > 0, "max must be between 1 and Int.max")
var buf:Array<CChar> = []
var c = getchar()
while c != EOF && c != 10 && buf.count < max {
buf.append(CChar(c))
c = getchar()
}
//always null terminate
buf.append(CChar(0))
return buf.withUnsafeBufferPointer { String.fromCString($0.baseAddress) }
}
答案 4 :(得分:5)
另一种方法是链接libedit以进行正确的行编辑(箭头键等)和可选的历史记录支持。我希望这是一个项目,我开始并组建一个basic example for how I set it up。
来自swift的用法
let prompt: Prompt = Prompt(argv0: C_ARGV[0])
while (true) {
if let line = prompt.gets() {
print("You typed \(line)")
}
}
ObjC包装器公开libedit
#import <histedit.h>
char* prompt(EditLine *e) {
return "> ";
}
@implementation Prompt
EditLine* _el;
History* _hist;
HistEvent _ev;
- (instancetype) initWithArgv0:(const char*)argv0 {
if (self = [super init]) {
// Setup the editor
_el = el_init(argv0, stdin, stdout, stderr);
el_set(_el, EL_PROMPT, &prompt);
el_set(_el, EL_EDITOR, "emacs");
// With support for history
_hist = history_init();
history(_hist, &_ev, H_SETSIZE, 800);
el_set(_el, EL_HIST, history, _hist);
}
return self;
}
- (void) dealloc {
if (_hist != NULL) {
history_end(_hist);
_hist = NULL;
}
if (_el != NULL) {
el_end(_el);
_el = NULL;
}
}
- (NSString*) gets {
// line includes the trailing newline
int count;
const char* line = el_gets(_el, &count);
if (count > 0) {
history(_hist, &_ev, H_ENTER, line);
return [NSString stringWithCString:line encoding:NSUTF8StringEncoding];
}
return nil;
}
@end
答案 5 :(得分:5)
一般来说, readLine()功能用于从控制台扫描输入。但是除非你添加&#34;命令行工具&#34; ,否则它在普通的iOS项目中不起作用。
最好的测试方法,你可以这样做:
import Foundation
print("Please enter some input\n")
if let response = readLine() {
print("output :",response)
} else {
print("Nothing")
}
Please enter some input
Hello, World
output : Hello, World
Program ended with exit code: 0
答案 6 :(得分:2)
以下是在基于控制台的应用程序上从用户获取输入的简单示例: 您可以使用readLine()。从控制台获取第一个数字的输入,然后按Enter键。然后输入第二个数字,如下图所示:
func solveMefirst(firstNo: Int , secondNo: Int) -> Int {
return firstNo + secondNo
}
let num1 = readLine()
let num2 = readLine()
var IntNum1 = Int(num1!)
var IntNum2 = Int(num2!)
let sum = solveMefirst(IntNum1!, secondNo: IntNum2!)
print(sum)
答案 7 :(得分:1)
快捷键5:如果您持续希望从键盘进行输入而不结束程序(如输入流),请执行以下步骤:
答案 8 :(得分:1)
此问题排名靠前的答案建议使用readLine()方法从命令行接收用户输入。但是,我想要注意你需要使用!调用此方法以返回字符串而不是可选的运算符:
var response = readLine()!
答案 9 :(得分:0)
import Foundation
print("Enter a number")
let number : Int = Int(readLine(strippingNewline: true)!) ?? 0
if(number < 5)
{
print("Small")
}else{
print("Big")
}
for i in 0...number{
print(i)
}
答案 10 :(得分:0)
var a;
scanf("%s\n", n);
我在ObjC中进行了测试,也许这会很有用。
答案 11 :(得分:0)
该问题有很多过时的答案。从Swift 2+开始,Swift标准库包含readline()函数。它会返回一个Optional,但只有在达到EOF时它才为零,当从键盘上获取输入时不会发生,因此在这些情况下可以安全地用力打开它。如果用户未输入任何内容,则其(未包装)值将为空字符串。这是一个小的实用程序函数,它使用递归来提示用户直到至少输入了一个字符:
func prompt(message: String) -> String {
print(message)
let input: String = readLine()!
if input == "" {
return prompt(message: message)
} else {
return input
}
}
let input = prompt(message: "Enter something!")
print("You entered \(input)")
请注意,使用可选绑定(如果让input = readLine())检查是否按照其他答案中的建议输入了某些内容,将不会达到预期的效果,因为它永远不会为零,并且在出现时至少为“”接受键盘输入。
这在无法访问命令提示符的Playground或任何其他环境中将不起作用。在命令行REPL中似乎也有问题。
答案 12 :(得分:0)
当在Xcode上运行readLine()函数时,调试控制台等待输入。输入完成后,其余代码将恢复。
let inputStr = readLine()
if let inputStr = inputStr {
print(inputStr)
}
答案 13 :(得分:0)
如果要读取空格分隔的字符串,并立即将字符串拆分为数组,则可以执行以下操作:
var arr = readLine()!.characters.split(" ").map(String.init)
例如
print("What is your full name?")
var arr = readLine()!.characters.split(" ").map(String.init)
var firstName = ""
var middleName = ""
var lastName = ""
if arr.count > 0 {
firstName = arr[0]
}
if arr.count > 2 {
middleName = arr[1]
lastName = arr[2]
} else if arr.count > 1 {
lastName = arr[1]
}
print("First Name: \(firstName)")
print("Middle Name: \(middleName)")
print("Last Name: \(lastName)")
答案 14 :(得分:0)
这适用于xCode v6.2,我认为是Swift v1.2
func input() -> String {
var keyboard = NSFileHandle.fileHandleWithStandardInput()
var inputData = keyboard.availableData
return NSString(data: inputData, encoding:NSUTF8StringEncoding)! as String
}
答案 15 :(得分:0)
答案 16 :(得分:0)
由于这个问题没有花哨的解决方案,我创建了一个小类来读取和解析Swift中的标准输入。你可以找到它here。
示例强>
解析:
+42 st_ring!
-0.987654321 12345678900
.42
你这样做:
let stdin = StreamScanner.standardInput
if
let i: Int = stdin.read(),
let s: String = stdin.read(),
let d: Double = stdin.read(),
let i64: Int64 = stdin.read(),
let f: Float = stdin.read()
{
print("\(i) \(s) \(d) \(i64) \(f)") //prints "42 st_ring! -0.987654321 12345678900 0.42"
}
答案 17 :(得分:0)
我向上帝发誓..这个完全基本的问题的解决方案在我看来已经没有了。它的很简单 ..但是那里有太多模糊/不好的信息;希望我可以保存某人 某些来自我最终的无底rabbit holes ......
那么,让我们得到一个&#34;字符串&#34;来自&#34;用户&#34;通过&#34;控制台&#34;,通过stdin
,我们?
[NSString.alloc initWithData:
[NSFileHandle.fileHandleWithStandardInput availableData]
encoding:NSUTF8StringEncoding];
如果你想要没有尾随换行符,只需添加...
[ ... stringByTrimmingCharactersInSet:
NSCharacterSet.newlineCharacterSet];
Ta Da!
♥ⱥᏪℯⅩ
答案 18 :(得分:-1)
我现在可以使用以下内容在Swift中获取键盘输入:
在我的main.swift文件中,我声明了一个变量i并为其分配了我在Objective C中定义的函数GetInt()。通过所谓的Bridging Header,我在其中声明了GetInt的函数原型,我可以链接到main。迅速。以下是文件:
main.swift:
var i: CInt = GetInt()
println("Your input is \(i) ");
桥接标题:
#include "obj.m"
int GetInt();
obj.m:
#import <Foundation/Foundation.h>
#import <stdio.h>
#import <stdlib.h>
int GetInt()
{
int i;
scanf("%i", &i);
return i;
}
在obj.m中可以包含c标准输出和输入,stdio.h,以及c标准库stdlib.h,它使您能够在Objective-C中用C编程,这意味着没有需要包含一个真正的swift文件,如user.c或类似的东西。
希望我能提供帮助,
编辑:无法通过C获取字符串输入,因为我在这里使用CInt - &gt; C的整数类型而不是Swift的整数类型。 C char *没有等效的Swift类型。因此String不能转换为字符串。但是这里有足够的解决方案来获取String输入。
劳尔
答案 19 :(得分:-1)
我只是想对xenadu的实现发表评论(我没有足够的代表),因为OS X中的CChar
是Int8
,而当你在{添加到数组时'时,Swift根本不喜欢{1}}返回UTF-8的部分或7位以上的任何其他内容。
我使用的是getchar()
数组,而且效果很好,UInt8
将String.fromCString
转换为UTF-8就好了。
然而,这就是我做的方式
UInt8