回答:
私はなんとか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
}
var input = NSString(data: NSFileHandle.fileHandleWithStandardInput().availableData, encoding:NSUTF8StringEncoding)
string.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet())
実際にはそれほど簡単ではありません。CAPIを操作する必要があります。に代わるものはありません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-Bridging-Header.h
void getInput(int *output);
編集 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) }
}
別の方法は、適切な行編集(矢印キーなど)とオプションの履歴サポートのためにlibeditをリンクすることです。私が始めているプロジェクトのためにこれが欲しかったし、それを設定する方法の基本的な例をまとめました。
迅速からの利用
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
一般に、コンソールからの入力をスキャンするために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
コンソールベースのアプリケーションでユーザーから入力を取得する簡単な例を次に示します。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)
私はこれを解決..神に誓って全く基本的な問題は何年も前に私の目を逃れて。それはだSOシンプル ..しかし、そこにそんなに曖昧/悪い情報があります。うまくいけば、私は保存することができ、誰かからいくつかの底なしのウサギの穴私が終わったことを...
それでは、のは経由して、「コンソール」を介して「ユーザー」から「文字列」を取得することができますstdin
、我々はなりませんか?
[NSString.alloc initWithData:
[NSFileHandle.fileHandleWithStandardInput availableData]
encoding:NSUTF8StringEncoding];
あなたがそれをしたい場合はなし改行、ちょうど追加...
[ ... stringByTrimmingCharactersInSet:
NSCharacterSet.newlineCharacterSet];
Ta Da!
♥ⱥᏪℯⅩ
この質問に対する多くの古い回答。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 let = readLine()の場合)を使用して、他の回答で提案されたとおりに何かが入力されたかどうかを確認することは、キーボード入力を受け入れるときにnilになることはなく、少なくとも ""になるため、望ましい効果はありません。
これは、コマンドプロンプトにアクセスできないPlaygroundやその他の環境では機能しません。コマンドラインREPLにも問題があるようです。
この問題に対する特別な解決策はなかったので、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"
}
スペースで区切られた文字列を読み取り、すぐに文字列を配列に分割する場合は、次のようにします。
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)")
XcodeでreadLine()関数を実行すると、デバッグコンソールは入力を待ちます。入力が完了すると、残りのコードが再開されます。
let inputStr = readLine()
if let inputStr = inputStr {
print(inputStr)
}
この質問に対する上位の回答は、readLine()メソッドを使用してコマンドラインからユーザー入力を取り込むことを示唆しています。ただし、!を使用する必要があることに注意してください。オプションの代わりに文字列を返すためにこのメソッドを呼び出すときの演算子:
var response = readLine()!
readLine()
が理由でオプションを返すのか、それゆえforce-unwrapは安全ではなく、実際には例に何も追加しません。
Swift 5:入力のストリームのように、プログラムを終了せずにキーボードからの入力を継続的に必要とする場合は、以下の手順を使用します。
タイプcomnnadラインツールの新しいプロジェクトを作成する
main.swiftファイルに以下のコードを追加します。
var inputArray = [String]()
while let input = readLine() {
guard input != "quit" else {
break
}
inputArray.append(input)
print("You entered: \(input)")
print(inputArray)
print("Enter a word:")
}
var a;
scanf("%s\n", n);
私はこれをObjCでテストしましたが、おそらくこれは役に立つでしょう。
xenaduの実装についてコメントしたい(十分な担当者がいない)のCChar
はInt8
、OS X ではでありgetchar()
、UTF-8の一部を返すときに配列に追加したり、7ビットを超えるものをSwiftがまったく好まなかったりするためです。
私はUInt8
代わりにの配列を使用していますが、それはうまく機能し、UTF-8にうまくString.fromCString
変換しUInt8
ます。
しかし、これは私がそれをやった方法です
func readln() -> (str: String?, hadError: Bool) {
var cstr: [UInt8] = []
var c: Int32 = 0
while c != EOF {
c = getchar()
if (c == 10 || c == 13) || c > 255 { break }
cstr.append(UInt8(c))
}
cstr.append(0)
return String.fromCStringRepairingIllFormedUTF8(UnsafePointer<CChar>(cstr))
}
while true {
if let mystring = readln().str {
println(" > \(mystring)")
}
}
以下を使用して、Swiftでキーボード入力を取得できるようになりました。
main.swiftファイルで、変数iを宣言し、それにObjective Cで定義した関数GetInt()を割り当てました。GetIntの関数プロトタイプを宣言した、いわゆるブリッジングヘッダーを介して、main.swiftにリンクできます。ここにファイルがあります:
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と、Objective-CのCでプログラミングできるようにするc標準ライブラリstdlib.hを含めることができます。つまり、含める必要はありません。 user.cのような実際の迅速なファイルまたはそのようなもの。
お役に立てれば幸いです。
編集:ここではCInt-> Cの整数型を使用しており、Swiftの整数型を使用していないため、Cを介して文字列入力を取得することはできません。C char *に相当するSwiftタイプはありません。したがって、文字列は文字列に変換できません。しかし、文字列入力を取得するために、この辺りにはかなり十分な解決策があります。
ラウル