कमांड लाइन एप्लिकेशन में कीबोर्ड से इनपुट


91

मैं नए Apple प्रोग्रामिंग भाषा स्विफ्ट के लिए कमांड लाइन ऐप के लिए कीबोर्ड इनपुट प्राप्त करने का प्रयास कर रहा हूं।

मैंने डॉक्स को बिना किसी लाभ के स्कैन किया है।

import Foundation

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

कोई विचार?

जवाबों:


135

ऐसा करने का सही तरीका readLineस्विफ्ट स्टैंडर्ड लाइब्रेरी से है।

उदाहरण:

let response = readLine()

आपको एक वैकल्पिक मान देगा जिसमें दर्ज किया गया पाठ होगा।


2
धन्यवाद। क्या पासवर्ड तरह का इनपुट प्राप्त करने का एक तरीका है?
अभिजीत गायकवाड़

मेरे लिए, यह सिर्फ प्रतिक्रिया = शून्य के साथ इस रेखा से गुजरती है। कुछ पता है कि समस्या क्या है?
पीटर वेब

4
@PeterWebb - xcode टर्मिनल में ठीक काम करता है, खेल के मैदान में गिरता है :)
aprofromindia

2
readLine को मूल उत्तरों में से अधिकांश के बाद जोड़ा गया था, इसलिए रवैया थोड़ा अनुचित है IMHO
russbishop

2
स्विफ्ट 3 के लिए सही, स्लिमजिम
ईजेकील एलिन

62

मैं सी में नीचे छोड़ने के बिना यह पता लगाने में कामयाब रहा:

मेरा समाधान इस प्रकार है:

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
}

5
मुझे यह पसंद है, यह भी, अगर आप किसी फ़ंक्शन को परिभाषित नहीं करना चाहते हैं, तो इसे एक पंक्ति में संकुचित किया जा सकता है, जैसे कि यदि आपको केवल एक कार्यक्रम में एक बार इनपुट स्वीकार करना है:var input = NSString(data: NSFileHandle.fileHandleWithStandardInput().availableData, encoding:NSUTF8StringEncoding)
jcmiller11

3
क्या मक्खी पर उपयोगकर्ता इनपुट को स्वीकार करने के लिए खेल के मैदान में इसका उपयोग करने का एक तरीका है?
रॉब कैमरन

5
आप खेल के मैदान में इसका इस्तेमाल नहीं कर सकते। आपको वहां चर का उपयोग करना होगा।
चाल्र्स

8
ध्यान दें कि आपको इसके साथ स्ट्रिंग में नए अंक मिलेंगे। स्ट्रिप उन्हेंstring.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet())
pk-nb

3
यदि उपयोगकर्ता किसी वर्ण को हटाता है, तो तीर कुंजी का उपयोग करता है, आदि भी आपको अजीब अक्षर मिलेंगे। AAAGGGGGHHHH WHY, Swift, Why?
यबकोस

13

यह वास्तव में इतना आसान नहीं है, आपको सी एपीआई के साथ बातचीत करनी होगी। का कोई विकल्प नहीं है 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);

ओह लड़का - काश, इससे अधिक तुच्छ कुछ और होता! मुझे पात्रों की एक स्ट्रिंग के लिए इसे अनुकूलित करना मुश्किल लग रहा है।
चालर्स

1
फ़ंक्शन परिभाषाओं को संग्रहीत करने के लिए "UserInput.h" बनाना बेहतर होगा, और इस फाइल को "cliinput-Bridging-Header.h" में शामिल किया जाएगा।
एलन ज़िलियांग फेंग

7

स्विफ्ट 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) }
}

मुझे स्विफ्टडॉक टिप्पणी पसंद है, और "सार्वजनिक" एक्सेस संशोधक, मैंने स्विफ्ट में उस तरह की चीज को पहले नहीं देखा था, लेकिन सीसीआर और सी-स्ट्रिंग सी और 8-बिट चरित्र सेट और स्विफ्ट के लिए एक थ्रोबैक लगता है। सभी यूनिकोड पाठ के बारे में है ... या सभी ASCII कमांड लाइन उपकरण हैं ??
कायडेल

2
मेरा मानना ​​है कि गेटचार्ज () एएससीआईआई रिटर्न करता है। यूनिकोड टर्मिनल एक पूरी बात है जो मैं नहीं चाहता था :)
russbishop

5

एक अन्य विकल्प उचित लाइन संपादन (तीर कुंजी, आदि) और वैकल्पिक इतिहास समर्थन के लिए 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

5

सामान्य रीडलाइन () फ़ंक्शन का उपयोग कंसोल से इनपुट को स्कैन करने के लिए किया जाता है। लेकिन यह सामान्य iOS प्रोजेक्ट में तब तक काम नहीं करेगा जब तक कि आप "कमांड-लाइन टूल" नहीं जोड़ते ।

परीक्षण के लिए सबसे अच्छा तरीका है, आप कर सकते हैं:

1. एक macOS फ़ाइल बनाएँ

यहां छवि विवरण दर्ज करें

2. कंसोल से वैकल्पिक स्ट्रिंग को स्कैन करने के लिए रीडलाइन () फंक का उपयोग करें

 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

यहां छवि विवरण दर्ज करें


3

यहाँ कंसोल आधारित एप्लिकेशन पर उपयोगकर्ता से इनपुट लेने का सरल उदाहरण है: आप रीडलाइन () का उपयोग कर सकते हैं। पहले नंबर के लिए कंसोल से इनपुट लें और फिर एंटर दबाएं। उसके बाद नीचे दिए गए चित्र में दिखाए अनुसार दूसरे नंबर के लिए इनपुट लें:

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)

उत्पादन


1

मैं भगवान की कसम खाता हूँ .. इस पूरी बुनियादी समस्या का हल मुझे YEARS के लिए मिला। यह बहुत आसान है .. लेकिन वहाँ बहुत अस्पष्ट / बुरी जानकारी है; उम्मीद है कि मैं किसी को कुछ अथाह खरगोश छेदों से बचा सकता हूं जिन्हें मैंने समाप्त किया ...

तो, चलो "कंसोल" के माध्यम से "उपयोगकर्ता" से "स्ट्रिंग" प्राप्त करते हैं stdin, हम कर सकते हैं ?

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

यदि आप इसे नई सीमा के बिना चाहते हैं , तो बस जोड़ें ...

[ ... stringByTrimmingCharactersInSet:
                       NSCharacterSet.newlineCharacterSet];

Ta Da! ♥ ᏪℯⅩ ᏪℯⅩ


4
स्विफ्ट, ओपी का कहना है कि स्विफ्ट।
हेनरीरूटटू 2

1
उन्होंने कहा ओएक्सएक्स। यह सब एक ही चीज़ के लिए संकलित है! अपने इनर-ओबजेक को गले लगाओ!
एलेक्स ग्रे

2
ऐसे लोग हैं जो स्विफ्ट में लिखते हैं और कभी भी उद्देश्य सी नहीं सीखेंगे। यह इस बारे में नहीं है कि यह किसके लिए संकलित है।
हेनरीरूटवू

1

इस सवाल का बहुत पुराना जवाब। स्विफ्ट 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 में भी समस्याएँ हैं।


0

चूंकि इस समस्या का कोई फैंसी समाधान नहीं था, इसलिए मैंने स्विफ्ट में मानक इनपुट पढ़ने और पार्स करने के लिए एक छोटी कक्षा बनाई। आप इसे यहाँ पा सकते हैं ।

उदाहरण

पार्स करने के लिए:

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

StreamScanner वर्ग का आयात कैसे करें?
टिमोथी स्वान

@TimothySwan, जैसा कि Readme के संस्थापन अनुभाग ( github.com/shoumikhin/StreamScanner#installation ) में बताया गया है । तो मूल रूप से आप बस अपने प्रोजेक्ट में StreamScanner.swift फ़ाइल जोड़ सकते हैं।
शौमिकिन


0

यह xCode v6.2 में काम करता है, मुझे लगता है कि यह स्विफ्ट v1.2 है

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

0

यदि आप अंतरिक्ष से अलग स्ट्रिंग पढ़ना चाहते हैं, और तुरंत स्ट्रिंग को एक सरणी में विभाजित करें, तो आप यह कर सकते हैं:

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

जब रीडलाइन () फ़ंक्शन Xcode पर चलाया जाता है, तो डिबग कंसोल इनपुट के लिए प्रतीक्षा करता है। इनपुट होने के बाद बाकी कोड फिर से शुरू किया जाएगा।

    let inputStr = readLine()
    if let inputStr = inputStr {
        print(inputStr)
    }

0

इस प्रश्न का शीर्ष रैंक उत्तर, कमांड लाइन से उपयोगकर्ता इनपुट में लेने के लिए रीडलाइन () विधि का उपयोग करने का सुझाव देता है। हालांकि, मैं यह नोट करना चाहता हूं कि आपको उपयोग करने की आवश्यकता है! ऑपरेटर जब वैकल्पिक के बजाय एक स्ट्रिंग वापस करने के लिए इस विधि को बुला रहा है:

var response = readLine()!

फोर्स-अनप्रैप क्यों, readLine()एक कारण के लिए वैकल्पिक रिटर्न करता है, इसलिए यह मजबूर-असुरक्षित के लिए असुरक्षित है और उदाहरण के लिए वास्तव में कुछ भी नहीं जोड़ता है।
कैंम्पस

0

स्विफ्ट 5: यदि आप लगातार प्रोग्राम को समाप्त किए बिना कीबोर्ड से इनपुट चाहते हैं, तो इनपुट की एक धारा की तरह, नीचे दिए चरणों का उपयोग करें:

  1. टाइप कॉमनड लाइन टूल का नया प्रोजेक्ट बनाएं कमांड लाइन परियोजना

    1. 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:")
      }   
    2. RunThe परियोजना और Xcode में उत्पाद फ़ोल्डर के तहत निष्पादन योग्य क्लिक करें और खोजक में खोलें
    3. इसे खोलने के लिए निष्पादन योग्य पर डबल क्लिक करें।
    4. अब अपना Input डालें। टर्मिनल कुछ इस तरह दिखेगा: यहां छवि विवरण दर्ज करें


-1

मैं सिर्फ xenadu के कार्यान्वयन पर टिप्पणी करना चाहता हूं (मेरे पास पर्याप्त प्रतिनिधि नहीं हैं), क्योंकि CCharOS 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)")
    }
}

-1

मैं अब निम्नलिखित का उपयोग करके स्विफ्ट में कीबोर्ड इनपुट प्राप्त करने में सक्षम हूं:

मेरी 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 * के लिए कोई समान स्विफ्ट प्रकार नहीं है। इसलिए स्ट्रिंग स्ट्रिंग के लिए परिवर्तनीय नहीं है। लेकिन स्ट्रिंग इनपुट प्राप्त करने के लिए यहां चारों ओर काफी पर्याप्त समाधान हैं।

राउल

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.