새로운 Apple 프로그래밍 언어 Swift에 대한 명령 줄 앱의 키보드 입력을 얻으려고합니다.
문서를 스캔하여 아무 소용이 없습니다.
import Foundation
println("What is your name?")
???
어떤 아이디어?
답변:
이를 수행하는 올바른 방법 readLine은 Swift Standard Library에서 를 사용하는 것 입니다.
예:
let response = readLine()
입력 한 텍스트가 포함 된 선택적 값을 제공합니다.
나는 C로 떨어지지 않고 그것을 알아낼 수 있었다.
내 솔루션은 다음과 같습니다.
func input() -> String {
var keyboard = NSFileHandle.fileHandleWithStandardInput()
var inputData = keyboard.availableData
return NSString(data: inputData, encoding:NSUTF8StringEncoding)!
}
최신 버전의 Xcode에는 명시적인 typecast가 필요합니다 (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())
실제로 그렇게 쉽지는 않습니다. 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-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) }
}
일반적으로 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
또 다른 대안은 적절한 행 편집 (화살표 키 등) 및 선택적 히스토리 지원을 위해 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 ()을 사용할 수 있습니다. 콘솔에서 첫 번째 숫자를 입력 한 다음 Enter 키를 누릅니다. 그 후 아래 이미지와 같이 두 번째 숫자를 입력하십시오.
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)
이 질문에 대한 오래된 답변이 많이 있습니다. Swift 2+부터 Swift Standard Library에는 readline () 함수 가 포함되어 있습니다 . Optional을 반환하지만 EOF에 도달 한 경우에만 nil이됩니다. 이는 키보드에서 입력을받을 때 발생하지 않으므로 이러한 시나리오에서 강제로 안전하게 풀 수 있습니다. 사용자가 아무것도 입력하지 않으면 (래핑되지 않은) 값은 빈 문자열이됩니다. 다음은 적어도 하나의 문자가 입력 될 때까지 사용자에게 메시지를 표시하기 위해 재귀를 사용하는 작은 유틸리티 함수입니다.
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)")
선택적 바인딩 (if let input = readLine ())을 사용하여 다른 답변에서 제안 된대로 입력되었는지 확인하면 키보드 입력을 수락 할 때 nil이 아니고 ""이상이되지 않으므로 원하는 효과가 없습니다.
플레이 그라운드 또는 명령 프롬프트에 액세스 할 수없는 기타 환경에서는 작동하지 않습니다. 명령 줄 REPL에도 문제가있는 것 같습니다.
나는 신에게 맹세한다.이 근본적인 문제에 대한 해결책 은 몇 년 동안 나를 피했다. 그건 너무 간단 ...하지만 훨씬 막연한 / 잘못된 정보가 부족하므로이있다; 다행스럽게도 필자는 절약 할 수 있는 사람 에서 약간 밑의 토끼 구멍 난에서 끝냈다을 ...
그럼,를 통해,의는 "콘솔"을 통해 "사용자"에서 "문자열"을 얻을 수 있습니다 stdin, 우리는해야 ?
[NSString.alloc initWithData:
[NSFileHandle.fileHandleWithStandardInput availableData]
encoding:NSUTF8StringEncoding];
후행 개행 없이 원하는 경우 추가하십시오 ...
[ ... stringByTrimmingCharactersInSet:
NSCharacterSet.newlineCharacterSet];
Ta Da! ♥ ⱥ ᏪℯⅩ
이 문제에 대한 멋진 해결책이 없었기 때문에 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)")
이 질문에 대한 최상위 답변은 readLine () 메서드를 사용하여 명령 줄에서 사용자 입력을받는 것을 제안합니다. 그러나 나는 당신이! 선택적 대신 문자열을 반환하기 위해이 메서드를 호출 할 때 연산자 :
var response = readLine()!
readLine()이 이유 때문에 선택 사항을 반환하는 이유는 force-unwrap이 안전하지 않으며 실제로 예제에 아무것도 추가하지 않습니다.
Swift 5 : 입력 스트림과 같이 프로그램을 종료하지 않고 키보드에서 계속 입력하려면 아래 단계를 사용하십시오.
comnnad line tool 유형의 새 프로젝트 만들기

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의 구현에 대해 언급하고 싶었습니다 (나는 충분한 담당자가 없습니다). 왜냐하면 CCharOS X에서는이고 Int8, 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에 대한 함수 프로토 타입을 선언 한 소위 Bridging Header를 통해 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-> Swift가 아닌 C의 정수 유형을 사용하고 있기 때문에 C를 통해 문자열 입력을 얻을 수 없습니다. C char *에 해당하는 Swift 유형은 없습니다. 따라서 문자열은 문자열로 변환 할 수 없습니다. 그러나 여기에는 문자열 입력을 얻기에 충분한 솔루션이 있습니다.
라울