在命令行应用程序中从键盘输入

Cha*_*ers 90 macos cocoa command-line swift

我正在尝试为新的Apple编程语言Swift获取命令行应用程序的键盘输入.

我扫描文档无济于事.

import Foundation

println("What is your name?")
???
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Eze*_*lin 131

正确的方法是使用readLineSwift标准库.

例:

let response = readLine()
Run Code Online (Sandbox Code Playgroud)

将为您提供包含输入文本的可选值.

  • @PeterWebb - 在xcode终端上工作正常,在操场上摔倒:) (4认同)
  • 谢谢。有没有办法获得密码类型的输入? (2认同)
  • readLine是在大部分原始答案之后添加的,所以态度有点无根据恕我直言 (2认同)
  • 更正了Swift 3,SlimJim (2认同)

Cha*_*ers 60

我设法解决了这个问题而没有进入C:

我的解决方案如下:

func input() -> String {
    var keyboard = NSFileHandle.fileHandleWithStandardInput()
    var inputData = keyboard.availableData
    return NSString(data: inputData, encoding:NSUTF8StringEncoding)!
}
Run Code Online (Sandbox Code Playgroud)

更新版本的Xcode需要一个明确的类型转换(适用于Xcode 6.4):

func input() -> String {
    var keyboard = NSFileHandle.fileHandleWithStandardInput()
    var inputData = keyboard.availableData
    return NSString(data: inputData, encoding:NSUTF8StringEncoding)! as String
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您将在此字符串中获取换行符.用`string.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet())去除它们. (8认同)
  • 我喜欢这个,如果你不想定义一个函数,它也可以压缩到一行,比如你只需要在程序中接受一次输入:`var input = NSString(data:NSFileHandle.fileHandleWithStandardInput( ).availableData,encoding:NSUTF8StringEncoding)` (5认同)
  • 你不能在操场上使用它.你必须在那里使用变量. (5认同)
  • 有没有办法在Playground中使用它来动态接受用户输入? (3认同)
  • 如果用户删除一个角色,使用箭头键等,你也会得到奇怪的角色.AUGAGGGGHHHH为什么,Swift,为什么? (3认同)
  • 在Swift 1.2中:`let inputString = NSString(data:inputData,encoding:NSUTF8StringEncoding)!as String` (2认同)

Lea*_*ros 13

它实际上并不那么容易,您必须与C API进行交互.没有其他选择scanf.我建立了一个小例子:

main.swift

import Foundation

var output: CInt = 0
getInput(&output)

println(output)
Run Code Online (Sandbox Code Playgroud)


UserInput.c

#include <stdio.h>

void getInput(int *output) {
    scanf("%i", output);
}
Run Code Online (Sandbox Code Playgroud)


cliinput桥接,Header.h

void getInput(int *output);
Run Code Online (Sandbox Code Playgroud)


rus*_*hop 7

编辑从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) }
}
Run Code Online (Sandbox Code Playgroud)

  • 我相信getchar()会返回ASCII.Unicode终端是我不想进入的整个事情:) (2认同)

Nei*_*eil 5

另一种方法是链接libedit以进行正确的行编辑(箭头键等)和可选的历史记录支持.我希望这是一个我正在开始的项目,并将我如何设置它基本示例放在一起.

来自swift的用法

let prompt: Prompt = Prompt(argv0: C_ARGV[0])

while (true) {
    if let line = prompt.gets() {
        print("You typed \(line)")
    }
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


Ash*_*aha 5

通常,readLine()函数用于从控制台扫描输入.但是除非你添加"命令行工具",否则它在普通的iOS项目中不起作用.

最好的测试方法,你可以做到:

1.创建一个macOS文件

在此输入图像描述

2.使用readLine()func从控制台扫描可选的String

 import Foundation

 print("Please enter some input\n")

 if let response = readLine() {
    print("output :",response)
 } else {
    print("Nothing")
 }
Run Code Online (Sandbox Code Playgroud)

输出:

Please enter some input

Hello, World
output : Hello, World
Program ended with exit code: 0
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述