कंसोल में मानक इनपुट से कैसे पढ़ें?


270

मैं कमांड लाइन से मानक इनपुट पढ़ना चाहता हूं, लेकिन इनपुट के लिए संकेत दिए जाने से पहले कार्यक्रम से बाहर निकलने के साथ मेरे प्रयास समाप्त हो गए हैं। मैं C # में Console.ReadLine () के समकक्ष देख रहा हूँ ।

वर्तमान में मेरे पास यही है:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter text: ")
    text, _ := reader.ReadString('\n')
    fmt.Println(text)

    fmt.Println("Enter text: ")
    text2 := ""
    fmt.Scanln(text2)
    fmt.Println(text2)

    ln := ""
    fmt.Sscanln("%v", ln)
    fmt.Println(ln)
}

यह कोड सही लगता है। जिज्ञासा से बाहर, क्या आप इसे खेल के मैदान पर चला रहे हैं? गो प्लेग्राउंड नेटवर्किंग कारणों से स्टड इनपुट की अनुमति नहीं देता है।
लीनियरजेट्रोपे

कोई बात नहीं, यह एक सूक्ष्म मुद्दा लगता है जहां आपको एक संकेतक की आवश्यकता थी (मेरा उत्तर देखें)। हालांकि मुझे यकीन नहीं है कि bufio.NewReader विधि में क्या समस्या है क्योंकि यह मेरे लिए काम करता है।
लिनियरजेट्रोपे


8
bufioकिसी भी पाठक की बफ़रिंग को मत मिलाओ (उदा bufio.NewReader(os.Stdin)) अंडरलाइनिंग रीडर से डायरेक्ट रीड (जैसे fmt.Scanln(x)सीधे से पढ़ता है os.Stdin) से। बफ़रिंग मनमाने ढंग से आगे तक पढ़ सकता है। (इस विशिष्ट मामले में बाद fmt.Fscanln(reader,x)में उसी बफर से पढ़ना चाहिए )।
डेव सी

मुझे काम नहीं मिलता fmt.Sscanlnहै, यह चलने के बाद "% v" हो जाता है
बीनो तुंग

जवाबों:


294

मुझे यकीन नहीं है कि ब्लॉक के साथ क्या गलत है

reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
fmt.Println(text)

जैसे यह मेरी मशीन पर काम करता है। हालाँकि, अगले ब्लॉक के लिए आपको उस वेरिएबल्स के लिए एक पॉइंटर की आवश्यकता होती है जिसे आप इनपुट को असाइन कर रहे हैं। के fmt.Scanln(text2)साथ बदलने का प्रयास करें fmt.Scanln(&text2)। उपयोग न करें Sscanln, क्योंकि यह स्टड से पहले से ही स्मृति में एक स्ट्रिंग को पार्स करता है। यदि आप कुछ ऐसा करना चाहते हैं जो आप करना चाह रहे थे, तो उसे बदलेंfmt.Scanf("%s", &ln)

यदि यह अभी भी काम नहीं करता है, तो आपका अपराधी कुछ अजीब सिस्टम सेटिंग्स या छोटी गाड़ी आईडीई हो सकता है।


2
क्या वे एकल उद्धरण होने चाहिए? ReadString('\n')या ReadString("\n")?
425nesp

8
@ ४२५ नं। हां, यह परिधि है, जो एक एकल बाइट है। golang.org/pkg/bufio/#Reader.ReadString
LinearZoetrope

3
अच्छा उत्तर, लेकिन यह तब विफल हो जाता है जब मैं बैकस्पेस, आदि कुंजियों का उपयोग करने की कोशिश करता हूं
कुमारहर्ष

4
इतना गोलांग के लिए पाठक rdसे चर के sरूप में फ़ाइल से एक लाइन को पढ़ने के लिएif s,_ = rd.ReadString('\n'); true { s = strings.Trim(s, " \n") }
Nam G VU

2
बस एक दिलचस्प बात साझा कर रहा हूं (मैं एक गोलंग शुरुआत हूं): \ n एकल उद्धरण के अंदर होना चाहिए (दोहरे उद्धरण चिह्नों का उपयोग करने की कोशिश न करें)। या फिर, यह इसे पुन: पेश करेगा:cannot use "\n" (type string) as type byte in argument to reader.ReadString
ivanleoncz

124

आप भी कोशिश कर सकते हैं:

scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

if scanner.Err() != nil {
    // handle error.
}

6
आप "{}" के लिए निकाल सकते हैं यदि आप केवल एक लाइन इनपुट चाहते हैं।
14:

3
अगर {} लूप के लिए है, तो जैसे ही आप एंटर करेंगे लूप से बाहर कैसे आएं? क्या कोई विशेष चरित्र है जो लूप को रोकने के लिए बनायेगा? -
साभार

2
@Madhan Scan.Scan () लूप के लिए बाहर निकलने का संकेत देने के लिए बूल मान लौटाता है या नहीं।
हेलिन वांग

5
आपको यह त्रुटि मिलेगी bufio.Scanner: टोकन बहुत लंबा है यदि आपका इनपुट 64 * 1024 बाइट्स से बड़ा है। इसके अलावा fmt.Println(scanner.Err())लूप के लिए नीचे जोड़ें मत भूलना ।
युवराज लोगनाथन 10

क्या होगा अगर मैं "abc \ n ^ D" दर्ज करता हूं, तो अपेक्षित स्ट्रिंग "abc \ n" है, लेकिन यह "abc" देता है।
शिवेंद्र मिश्र

96

मुझे लगता है कि ऐसा करने के लिए एक अधिक मानक तरीका होगा:

package main

import "fmt"

func main() {
    fmt.Print("Enter text: ")
    var input string
    fmt.Scanln(&input)
    fmt.Print(input)
}

scanगोडॉक पर एक नज़र डालें: http://godoc.org/fmt#Scan

मानक इनपुट से पढ़ा गया स्कैन स्कैन पाठ, क्रमिक स्थान-पृथक मानों को क्रमिक तर्कों में संग्रहीत करता है। अंतरिक्ष में न्यूलाइन्स की गिनती होती है।

Scanln स्कैन के समान है, लेकिन एक नई रेखा पर स्कैन करना बंद कर देता है और अंतिम आइटम के बाद एक नई पंक्ति या EOF होना चाहिए।


10
यह इनपुट स्ट्रिंग में रिक्त स्थान को पसंद नहीं करता है।
बालों वाली क्रिस

3
@ हर्षलक्रिस हाँ यह अजीब है। डॉक्टर में यह कहा गया है कि stops scanning at a newline and after the final item there must be a newline or EOFइतना निश्चित नहीं है कि क्यों अंतरिक्ष "इसे" तोड़ता है ... मुझे लगता है कि यह एक बग है
किरासन

6
इसके लिए एक बग खोला गया था: github.com/golang/go/issues/5703 यह कार्यकारिणी के रूप में बंद हो गया। इसे भी देखें: stackoverflow.com/questions/24005899/… और group.google.com/forum/# ​​.topic/golang - nuts/r6Jl4D9Juw0 बहुत से लोगों को इसके साथ समस्याएँ आती हैं । प्रलेखन परिवर्तन की आवश्यकता है? इसके अलावा, उस अंतिम लिंक से: "स्कैन और स्केनलन पार्सिंग और उस तरह के सामान के लिए हैं, इसलिए स्टड से पाठ की एक भी पंक्ति प्राप्त करना उद्देश्य को हरा देगा।"
user2707671

मेरे लिए, यह वास्तव में भ्रमित करने वाला है कि fmt.Scan अपने समान कार्यों में से किसी भी रिक्त स्थान के साथ अच्छी तरह से नहीं खेलता है जैसे bufio.NewReader करता है।
फिलबोट 3

3
उपयोग करते समय fmt.Scanlnऔर fmt.Scanचालू 2016 गो संस्करण के साथ रिक्त स्थान के साथ भी यही समस्या है (go version go1.6.2 linux / amd64)।
चिहेब नेक्सस

30

हमेशा bufio.NewScanner का उपयोग करने का प्रयास करें कंसोल से इनपुट एकत्र । जैसा कि दूसरों ने उल्लेख किया है, नौकरी करने के कई तरीके हैं लेकिन मूल रूप से स्कैनर का उद्देश्य नौकरी करना है। डेव चेनी बताते हैं कि आपको bufio.eader के ReadLine के बजाय Scanner का उपयोग क्यों करना चाहिए।

https://twitter.com/davecheney/status/604837853344989184?lang=en

यहाँ आपके प्रश्न के लिए कोड स्निपेट उत्तर है

package main

import (
    "bufio"
    "fmt"
    "os"
)

/*
 Three ways of taking input
   1. fmt.Scanln(&input)
   2. reader.ReadString()
   3. scanner.Scan()

   Here we recommend using bufio.NewScanner
*/

func main() {
    // To create dynamic array
    arr := make([]string, 0)
    scanner := bufio.NewScanner(os.Stdin)
    for {
        fmt.Print("Enter Text: ")
        // Scans a line from Stdin(Console)
        scanner.Scan()
        // Holds the string that scanned
        text := scanner.Text()
        if len(text) != 0 {
            fmt.Println(text)
            arr = append(arr, text)
        } else {
            break
        }

    }
    // Use collected inputs
    fmt.Println(arr)
}

यदि आप प्रोग्रामेटिक रूप से इनपुट एकत्र नहीं करना चाहते हैं, तो बस इन पंक्तियों को जोड़ें

   scanner := bufio.NewScanner(os.Stdin)
   scanner.Scan()
   text := scanner.Text()
   fmt.Println(text)

उपरोक्त कार्यक्रम का उत्पादन होगा:

Enter Text: Bob
Bob
Enter Text: Alice
Alice
Enter Text:
[Bob Alice]

उपरोक्त कार्यक्रम उपयोगकर्ता इनपुट एकत्र करता है और उन्हें एक सरणी में सहेजता है। हम एक विशेष चरित्र के साथ उस प्रवाह को भी तोड़ सकते हैं। स्कैनर उन्नत उपयोग के लिए एपीआई प्रदान करता है जैसे कि कस्टम फ़ंक्शन का उपयोग करके विभाजन करना, विभिन्न प्रकार के I / O स्ट्रीम (स्टडिन, स्ट्रिंग) आदि को स्कैन करना।


यह स्वीकृत उत्तर होना चाहिए। न केवल यह अधिक सटीक उत्तर है बल्कि बेहतर गुणवत्ता का है।
डैनियल फैरेल

11

लूप के भीतर एक से अधिक इनपुट पढ़ने का दूसरा तरीका जो रिक्त स्थान के साथ एक इनपुट को संभाल सकता है:

package main
import (
    "fmt"
    "bufio"
    "os"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    var text string
    for text != "q" {  // break the loop if text == "q"
        fmt.Print("Enter your text: ")
        scanner.Scan()
        text = scanner.Text()
        if text != "q" {
            fmt.Println("Your text was: ", text)
        }
    }
}

आउटपुट:

Enter your text: Hello world!
Your text was:  Hello world!
Enter your text: Go is awesome!
Your text was:  Go is awesome!
Enter your text: q

2
आप शायद आंतरिक "क्यू" चेक में ब्रेक का उपयोग कर सकते हैं और इसे अनंत लूप में लपेट सकते हैं। वैसे शानदार जवाब!
टेबनीप

2
लगता है कि आप लूप के लिए भी सशर्त से छुटकारा पा सकते हैं।
इरिबनाना

6

मुझे पार्टी की देर है। लेकिन कैसे एक लाइनर के बारे में:

data, err := ioutil.ReadAll(os.Stdin)

कमांड लाइन पर इनपुट दर्ज करने के बाद ctrl + d (EOT) दबाएं।


क्योंकि os.Stdin'अंत' नहीं है, यह सब पढ़ना असंभव है। आप थोड़ी देर इंतजार कर सकते हैं ...
gypsydave5

2
ctrl + d यानी eot दबाएँ।
शिवेंद्र मिश्रा

3
हां, ऐसा करना - मुझे ईमेल लिखने की याद दिलाता है mail
जिप्सीडेव ५

5

इस कोड को आज़माएं: -

var input string
func main() {
      fmt.Print("Enter Your Name=")
      fmt.Scanf("%s",&input)
      fmt.Println("Hello "+input)
      }

3
लगता है जैसे Scanf()स्ट्रिंग में सफेद रिक्त स्थान स्वीकार नहीं करता है
Eslam

4

इस तरह भी किया जा सकता है: -

package main
import "fmt"     

func main(){
    var myname string
fmt.Scanf("%s", &myname)           
fmt.Println("Hello", myname)       
}

3

साफ-साफ एक जोड़े में पढ़ा मूल्यों को प्रेरित किया:

// Create a single reader which can be called multiple times
reader := bufio.NewReader(os.Stdin)
// Prompt and read
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
fmt.Print("Enter More text: ")
text2, _ := reader.ReadString('\n')
// Trim whitespace and print
fmt.Printf("Text1: \"%s\", Text2: \"%s\"\n",
    strings.TrimSpace(text), strings.TrimSpace(text2))

यहाँ एक रन है:

Enter text: Jim
Enter More text: Susie
Text1: "Jim", Text2: "Susie"

2
तार के बाद से भी एक अच्छा तरीका है। ट्रिमस्पेस '\ n' को हटाता है। और मेरा मानना ​​है कि पाठक। रीडस्ट्रीमिंग ('\ n') क्रॉस प्लेटफॉर्म भी है।
14:

मुझे लगता है कि ज्यादातर समय आप डिफ़ॉल्ट रूप से \ n हटाना चाहते हैं, इसीलिए यह बेहतर है bufio.NewScanner @Naren Yellavula जवाब के रूप में
John Balvin Arias


0

मेरे मामले में, प्रोग्राम प्रतीक्षा नहीं कर रहा था क्योंकि मैं watcherप्रोग्राम को ऑटो चलाने के लिए कमांड का उपयोग कर रहा था । कार्यक्रम को मैन्युअल रूप से चलाने के go run main.goपरिणामस्वरूप "टेक्स्ट दर्ज करें" और अंततः कंसोल को प्रिंट किया गया।

fmt.Print("Enter text: ")
var input string
fmt.Scanln(&input)
fmt.Print(input)

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