जवाबों:
ऐसा करने का सही तरीका readLine
स्विफ्ट स्टैंडर्ड लाइब्रेरी से है।
उदाहरण:
let response = readLine()
आपको एक वैकल्पिक मान देगा जिसमें दर्ज किया गया पाठ होगा।
मैं सी में नीचे छोड़ने के बिना यह पता लगाने में कामयाब रहा:
मेरा समाधान इस प्रकार है:
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())
यह वास्तव में इतना आसान नहीं है, आपको सी एपीआई के साथ बातचीत करनी होगी। का कोई विकल्प नहीं है 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-ब्रिजिंग-Header.h
void getInput(int *output);
स्विफ्ट 2.2 का संपादन मानक पुस्तकालय में शामिल है readLine
। मैं यह भी नोट करूंगा कि स्विफ्ट ने डॉकडाउन डॉक टिप्पणियों पर स्विच किया। ऐतिहासिक संदर्भ के लिए मेरे मूल उत्तर को छोड़कर।
पूर्णता के लिए, यहां मैं एक स्विफ्ट कार्यान्वयन का readln
उपयोग कर रहा हूं। आपके पास बाइट्स की अधिकतम संख्या को इंगित करने के लिए एक वैकल्पिक पैरामीटर है जिसे आप पढ़ना चाहते हैं (जो स्ट्रिंग की लंबाई हो सकती है या नहीं भी हो सकती है)।
यह भी swiftdoc टिप्पणियों के उचित उपयोग को दर्शाता है - स्विफ्ट एक <प्रोजेक्ट> .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)")
}
}
परिवाद का खुलासा करने के लिए ओबीजीसी रैपर
#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
सामान्य रीडलाइन () फ़ंक्शन का उपयोग कंसोल से इनपुट को स्कैन करने के लिए किया जाता है। लेकिन यह सामान्य 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
यहाँ कंसोल आधारित एप्लिकेशन पर उपयोगकर्ता से इनपुट लेने का सरल उदाहरण है: आप रीडलाइन () का उपयोग कर सकते हैं। पहले नंबर के लिए कंसोल से इनपुट लें और फिर एंटर दबाएं। उसके बाद नीचे दिए गए चित्र में दिखाए अनुसार दूसरे नंबर के लिए इनपुट लें:
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)
मैं भगवान की कसम खाता हूँ .. इस पूरी बुनियादी समस्या का हल मुझे YEARS के लिए मिला। यह बहुत आसान है .. लेकिन वहाँ बहुत अस्पष्ट / बुरी जानकारी है; उम्मीद है कि मैं किसी को कुछ अथाह खरगोश छेदों से बचा सकता हूं जिन्हें मैंने समाप्त किया ...
तो, चलो "कंसोल" के माध्यम से "उपयोगकर्ता" से "स्ट्रिंग" प्राप्त करते हैं stdin
, हम कर सकते हैं ?
[NSString.alloc initWithData:
[NSFileHandle.fileHandleWithStandardInput availableData]
encoding:NSUTF8StringEncoding];
यदि आप इसे नई सीमा के बिना चाहते हैं , तो बस जोड़ें ...
[ ... stringByTrimmingCharactersInSet:
NSCharacterSet.newlineCharacterSet];
Ta Da!
♥ ᏪℯⅩ ᏪℯⅩ
इस सवाल का बहुत पुराना जवाब। स्विफ्ट 2+ के रूप में स्विफ्ट स्टैंडर्ड लाइब्रेरी में रीडलाइन () फ़ंक्शन होता है। यह एक वैकल्पिक लौटाएगा, लेकिन यह केवल तभी शून्य होगा जब ईओएफ पहुंच गया है, जो कीबोर्ड से इनपुट प्राप्त करते समय नहीं होगा, इसलिए यह उन परिदृश्यों में बल द्वारा सुरक्षित रूप से अलिखित हो सकता है। यदि उपयोगकर्ता कुछ भी दर्ज नहीं करता है, तो इसका अपरिवर्तित मूल्य खाली स्ट्रिंग होगा। यहां एक छोटी उपयोगिता फ़ंक्शन है जो उपयोगकर्ता को संकेत देने के लिए पुनरावृत्ति का उपयोग करता है जब तक कि कम से कम एक वर्ण दर्ज नहीं किया गया हो:
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)")
ध्यान दें कि वैकल्पिक बंधन का उपयोग करते हुए (यदि इनपुट = readLine ()) यह जांचने के लिए कि क्या कुछ अन्य उत्तरों में प्रस्तावित के रूप में दर्ज किया गया है, तो वांछित प्रभाव नहीं होगा, क्योंकि यह कीबोर्ड इनपुट स्वीकार करते समय कभी भी शून्य और कम से कम "" नहीं होगा।
यह एक खेल का मैदान या किसी अन्य वातावरण में काम नहीं करेगा जहां आपके पास कमांड प्रॉम्प्ट तक पहुंच नहीं है। ऐसा लगता है कि कमांड-लाइन REPL में भी समस्याएँ हैं।
चूंकि इस समस्या का कोई फैंसी समाधान नहीं था, इसलिए मैंने स्विफ्ट में मानक इनपुट पढ़ने और पार्स करने के लिए एक छोटी कक्षा बनाई। आप इसे यहाँ पा सकते हैं ।
उदाहरण
पार्स करने के लिए:
+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"
}
यह xCode v6.2 में काम करता है, मुझे लगता है कि यह स्विफ्ट v1.2 है
func input() -> String {
var keyboard = NSFileHandle.fileHandleWithStandardInput()
var inputData = keyboard.availableData
return NSString(data: inputData, encoding:NSUTF8StringEncoding)! as String
}
यदि आप अंतरिक्ष से अलग स्ट्रिंग पढ़ना चाहते हैं, और तुरंत स्ट्रिंग को एक सरणी में विभाजित करें, तो आप यह कर सकते हैं:
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)")
इस प्रश्न का शीर्ष रैंक उत्तर, कमांड लाइन से उपयोगकर्ता इनपुट में लेने के लिए रीडलाइन () विधि का उपयोग करने का सुझाव देता है। हालांकि, मैं यह नोट करना चाहता हूं कि आपको उपयोग करने की आवश्यकता है! ऑपरेटर जब वैकल्पिक के बजाय एक स्ट्रिंग वापस करने के लिए इस विधि को बुला रहा है:
var response = readLine()!
readLine()
एक कारण के लिए वैकल्पिक रिटर्न करता है, इसलिए यह मजबूर-असुरक्षित के लिए असुरक्षित है और उदाहरण के लिए वास्तव में कुछ भी नहीं जोड़ता है।
स्विफ्ट 5: यदि आप लगातार प्रोग्राम को समाप्त किए बिना कीबोर्ड से इनपुट चाहते हैं, तो इनपुट की एक धारा की तरह, नीचे दिए चरणों का उपयोग करें:
टाइप कॉमनड लाइन टूल का नया प्रोजेक्ट बनाएं
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);
मैंने इसे ओबीजेसी में परीक्षण किया, और शायद यह उपयोगी होगा।
मैं सिर्फ xenadu के कार्यान्वयन पर टिप्पणी करना चाहता हूं (मेरे पास पर्याप्त प्रतिनिधि नहीं हैं), क्योंकि CChar
OS X में है Int8
, और जब आप सरणी में जोड़ते हैं तो स्विफ्ट बिल्कुल पसंद नहीं करता हैgetchar()
UTF-8 के कुछ हिस्सों, या 7 बिट से ऊपर कुछ भी लौटाते हैं ।
मैं UInt8
इसके बजाय एक सरणी का उपयोग कर रहा हूं , और यह महान काम करता है और String.fromCString
धर्मान्तरित करता हैUInt8
UTF-8 में है।
हालाँकि यह मैंने कैसे किया है
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)")
}
}
मैं अब निम्नलिखित का उपयोग करके स्विफ्ट में कीबोर्ड इनपुट प्राप्त करने में सक्षम हूं:
मेरी main.swift फाइल में मैंने एक वेरिएबल i घोषित किया और इसे फ़ंक्शन GetInt () को सौंपा, जिसे मैंने Objective C. में परिभाषित किया। एक तथाकथित ब्रिजिंग हेडर के माध्यम से जहाँ मैंने GetInt के लिए फ़ंक्शन प्रोटोटाइप को घोषित किया, मैं मुख्य .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, साथ ही c मानक लाइब्रेरी stdlib.h को शामिल करना संभव है, जो आपको C को Objective-C में प्रोग्राम करने में सक्षम बनाता है, जिसका अर्थ है कि इसमें शामिल होने की कोई आवश्यकता नहीं है। एक वास्तविक स्विफ्ट फ़ाइल जैसे user.c या ऐसा कुछ।
आशा है कि मैं मदद कर सकता हूँ,
संपादित करें: स्ट्रिंग इनपुट को C के माध्यम से प्राप्त करना संभव नहीं है क्योंकि यहां मैं CInt का उपयोग कर रहा हूं -> C का पूर्णांक प्रकार और स्विफ्ट का नहीं। C char * के लिए कोई समान स्विफ्ट प्रकार नहीं है। इसलिए स्ट्रिंग स्ट्रिंग के लिए परिवर्तनीय नहीं है। लेकिन स्ट्रिंग इनपुट प्राप्त करने के लिए यहां चारों ओर काफी पर्याप्त समाधान हैं।
राउल