Vraag Invoer via het toetsenbord in opdrachtregeltoepassing


Ik probeer de toetsenbordinvoer voor een opdrachtregelapp voor de nieuwe Apple-programmeertaal Swift te krijgen.

Ik heb de documenten niet gescand.

import Foundation

println("What is your name?")
???

Om het even welke ideeën?


82
2018-06-02 23:15


oorsprong


antwoorden:


De juiste manier om dit te doen is om te gebruiken readLine, van de Swift Standard Library.

Voorbeeld:

let response = readLine()

Geeft u een optionele waarde met de ingevoerde tekst.


112
2017-12-07 21:55



Ik ben erin geslaagd om erachter te komen zonder naar C af te dalen:

Mijn oplossing is als volgt:

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

Meer recente versies van Xcode hebben een expliciete typecast nodig (werkt in Xcode 6.4):

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

58
2018-06-03 17:32



Het is eigenlijk niet zo eenvoudig, je moet interactie hebben met de C API. Er is geen alternatief voor scanf. Ik heb een klein voorbeeld gemaakt:

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-Bridging-header.h

void getInput(int *output);

13
2018-06-02 23:49



Bewerk Vanaf Swift 2.2 omvat de standaardbibliotheek readLine. Ik merk ook op dat Swift is overgestapt op het markeren van documentcommentaren. Mijn origineel antwoord achterlaten voor historische context.

Alleen voor de volledigheid, hier is een snelle implementatie van readln Ik heb gebruikt. Het heeft een optionele parameter om het maximale aantal bytes aan te geven dat u wilt lezen (dit kan de lengte van de tekenreeks zijn).

Dit toont ook het juiste gebruik van swiftdoc-opmerkingen aan - Swift genereert een <project> .swiftdoc-bestand en Xcode zal het gebruiken.

///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) }
}

6
2017-07-30 16:53



Een ander alternatief is om te linken libedit voor juiste regelbewerking (pijltoetsen, enz.) en optionele geschiedenisondersteuning. Ik wilde dit voor een project dat ik aan het opstarten en samen stel eenvoudig voorbeeld voor hoe ik het opzet.

Gebruik van snel

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

while (true) {
    if let line = prompt.gets() {
        print("You typed \(line)")
    }
}

ObjC-wrapper om libedit te tonen

#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
2018-06-10 10:02



In het algemeen Lees regel() functie wordt gebruikt voor het scannen van invoer vanaf console. Maar het zal niet werken in een normaal iOS-project tot of zonder toevoeging "opdrachtregelprogramma".

De beste manier om te testen, kunt u doen:

1. Maak een macOS-bestand

enter image description here

2. Gebruik de functie readLine () om de optionele String van console te scannen

 import Foundation

 print("Please enter some input\n")

 if let response = readLine() {
    print("output :",response)
 } else {
    print("Nothing")
 }

Output:

Please enter some input

Hello, World
output : Hello, World
Program ended with exit code: 0

enter image description here


5
2017-12-19 04:51



Hier is een eenvoudig voorbeeld van het betrekken van de gebruiker bij een console-gebaseerde applicatie: U kunt readLine () gebruiken. Neem input van console voor eerste nummer en druk op enter. Neem daarna de invoer voor het tweede nummer zoals getoond in de afbeelding hieronder:

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)

Output


2
2018-02-12 07:07



Omdat er geen fraaie oplossingen voor dit probleem waren, heb ik een kleine klas gemaakt om de standaardinvoer in Swift te lezen en te analyseren. Je kan het vinden hier.

Voorbeeld

Ontleden:

+42 st_ring!
-0.987654321 12345678900
.42

Je doet:

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"
}

0
2018-06-29 07:13