web-dev-qa-db-ja.com

コマンドラインアプリケーションのキーボードからの入力

新しいAppleプログラミング言語Swiftのコマンドラインアプリのキーボード入力を取得しようとしています。

私はドキュメントをスキャンしましたが、役に立ちませんでした。

import Foundation

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

何か案は?

89
Chalkers

私は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
}
60
Chalkers

これを行う正しい方法は、Swift標準ライブラリの readLine を使用することです。

例:

let response = readLine()

入力したテキストを含むオプションの値を提供します。

125
Ezekiel Elin

実際にはそれほど簡単ではありません。CAPIを操作する必要があります。 scanfに代わるものはありません。私は小さな例を構築しました:

main.Swift

import Foundation

var output: CInt = 0
getInput(&output)

println(output)


serInput.c

#include <stdio.h>

void getInput(int *output) {
    scanf("%i", output);
}


cliinput-Bridging-Header.h

void getInput(int *output);
13
Leandros

編集 Swift 2.2現在、標準ライブラリにはreadLineが含まれています。また、Swiftがマークダウンドキュメントコメントに切り替えられたことにも注意してください。歴史的な文脈のために私の元の答えを残します。

完全を期すために、これは私が使用しているreadlnのSwift実装です。読み取るバイトの最大数(文字列の長さである場合とそうでない場合がある)を示すオプションのパラメーターがあります。

これは、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) }
}
7
russbishop

一般に 読み込まれた行() 関数は、コンソールからの入力をスキャンするために使用されます。ただし、追加するまで、または追加しない限り、通常のiOSプロジェクトでは機能しません。 「コマンドラインツール」

テストのための最良の方法は、あなたがすることができます:

1. macOSファイルを作成する

enter image description here

2. readLine()funcを使用して、コンソールからオプションの文字列をスキャンします

 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

enter image description here

5
Ashis Laha

別の方法は、適切な行編集(矢印キーなど)およびオプションの履歴サポートのために libedit をリンクすることです。私が始めようとしているプロジェクトのためにこれを望み、 私がそれを設定する方法の基本的な例 をまとめました。

Swiftからの使用

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

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

Libeditを公開するObjCラッパー

#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
Neil

コンソールベースのアプリケーションでユーザーから入力を取得する簡単な例を次に示します。readLine()を使用できます。コンソールから最初の番号を入力し、Enterキーを押します。その後、次の図に示すように、2番目の数値の入力を取得します。

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
Shehzad Ali

この質問に対するトップランクの回答は、readLine()メソッドを使用してコマンドラインからユーザー入力を取り込むことを提案しています。ただし、!を使用する必要があることに注意してください。このメソッドを呼び出して、オプションではなく文字列を返すときの演算子:

var response = readLine()!
1
topherPedersen

スペースで区切られた文字列を読み取り、すぐに文字列を配列に分割する場合、これを行うことができます:

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)")
0
Brian Ho

ReadLine()関数がXcodeで実行されると、デバッグコンソールは入力を待ちます。入力が完了すると、残りのコードが再開されます。

    let inputStr = readLine()
    if let inputStr = inputStr {
        print(inputStr)
    }
0
Sourabh Shekhar

Before

enter image description here

*******************。

修正

enter image description here

0
Murphy

この質問に対する古い回答がたくさんあります。 Swift 2+現在、Swift標準ライブラリには readline() 関数が含まれています。 Optionalを返しますが、EOFに達した場合にのみnilになります。これは、キーボードから入力を取得するときに発生しないため、これらのシナリオで強制的に安全にアンラップできます。ユーザーが何も入力しない場合、その(ラップされていない)値は空の文字列になります。再帰を使用して、少なくとも1文字が入力されるまでユーザーにプロンプ​​トを表示する小さなユーティリティ関数を次に示します。

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()の場合)を使用して、他の回答で提案されたとおりに入力されたかどうかをチェックすると、nilではなく、少なくともキーボード入力を受け入れる場合は「」。

これは、プレイグラウンドや、コマンドプロンプトにアクセスできない他の環境では機能しません。コマンドラインREPLにも問題があるようです。

0

この問題に対する優れた解決策はなかったため、Swiftで標準入力を読み取って解析するための小さなクラスを作成しました。あなたはそれを見つけることができます こちら

パースします:

+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"
}
0
shoumikhin

これは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
}
0
Giant Elk

私は神に誓います。このまったく基本的な問題の解決策は、私がYEARSのために逃げた。 SO simple..しかし、そこには非常に曖昧な/悪い情報がたくさんあります。うまくいけば、someonesomeの底なし ウサギの穴 から保存できます。 。

それでは、「コンソール」、stdinshall weを介して、「ユーザー」から「文字列」を取得しましょう。

[NSString.alloc initWithData:
[NSFileHandle.fileHandleWithStandardInput availableData]
                          encoding:NSUTF8StringEncoding];

必要に応じて末尾の改行なしで、追加するだけです...

[ ... stringByTrimmingCharactersInSet:
                       NSCharacterSet.newlineCharacterSet];

Ta Da!♥ⱥᏪℯⅩ

0
Alex Gray