我正在尝试为新的Apple编程语言Swift获取命令行应用程序的键盘输入.
我扫描文档无济于事.
import Foundation println("What is your name?") ???
有任何想法吗?
正确的方法是使用readLine
Swift标准库.
例:
let response = readLine()
将为您提供包含输入文本的可选值.
我设法解决了这个问题而没有进入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 }
它实际上并不那么容易,您必须与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);
另一种方法是链接libedit以进行正确的行编辑(箭头键等)和可选的历史记录支持.我希望这是一个我正在开始的项目,并将我如何设置它的基本示例放在一起.
来自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
通常,readLine()函数用于从控制台扫描输入.但是除非你添加"命令行工具",否则它在普通的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
编辑从Swift 2.2开始,标准库包括readLine
.我还会注意到Swift切换到降价文档评论.留下我对历史背景的原始答案.
为了完整起见,这是readln
我一直在使用的Swift实现.它有一个可选参数,用于指示要读取的最大字节数(可能是也可能不是String的长度).
这也证明了正确使用swiftdoc注释 - Swift将生成一个<project> .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) } }