2013-02-01 40 views
5

यहां एक मुद्दा है जो इस समय मुझे बेकार कर रहा है। जब उपयोगकर्ता से इनपुट हो रही है, मैं फिर से प्रयास करना, जब तक वे मान्य इनपुट दर्ज उपयोगकर्ता पूछने के लिए एक पाश को रोजगार के लिए चाहते हैं:,Fmt.Scanf() में जाने के बाद Stdin कैसे फ़्लश करें?

// user_input.go 
package main 

import (
    "fmt" 
) 

func main() { 
    fmt.Println("Please enter an integer: ") 

    var userI int 

    for { 
     _, err := fmt.Scanf("%d", &userI) 
     if err == nil { 
      break 
     } 
     fmt.Println("Sorry, invalid input. Please enter an integer: ") 
    } 

    fmt.Println(userI)  
} 

ऊपर चल रहा है उपयोगकर्ता मान्य इनपुट दर्ज करता है तो कोई समस्या नहीं:

एक पूर्णांक दर्ज करें:


बाहर निकलें कोड 0, प्रक्रिया सामान्य रूप से बाहर निकल गया।

लेकिन इसके बजाय एक स्ट्रिंग इनपुट करने का प्रयास करें?

कृपया एक पूर्णांक दर्ज करें: क्या?
क्षमा करें, अमान्य इनपुट। कृपया एक पूर्णांक दर्ज करें:
क्षमा करें, अमान्य इनपुट। कृपया एक पूर्णांक दर्ज करें:
क्षमा करें ...

आदि, और स्ट्रिंग समाप्त होने तक यह चरित्र द्वारा लूपिंग चरित्र रखता है। यहां तक ​​कि एक वर्ण को दो बार लूप करने में भी, मुझे लगता है क्योंकि यह नई लाइन को पार करता है।

वैसे भी, गो में स्टडिन फ्लश करने का कोई तरीका होना चाहिए?

पीएस ऐसी सुविधा की अनुपस्थिति में, आप समकक्ष कार्यक्षमता प्रदान करने के लिए इसके आसपास कैसे काम करेंगे? मैं उस पर भी असफल रहा हूं ...

उत्तर

3

मैं प्रत्येक विफलता के बाद लाइन के अंत तक इसे पढ़कर ठीक कर दूंगा। यह शेष पाठ को साफ़ करता है।

package main 

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

func main() { 
    stdin := bufio.NewReader(os.Stdin) 

    fmt.Println("Please enter an integer: ") 

    var userI int 

    for { 
     _, err := fmt.Fscan(stdin, &userI) 
     if err == nil { 
      break 
     } 

     stdin.ReadString('\n') 
     fmt.Println("Sorry, invalid input. Please enter an integer: ") 
    } 

    fmt.Println(userI) 
} 
+0

यह एक अच्छा कामकाज है। धन्यवाद! –

+0

केवल 'स्कैनल' का उपयोग करें जिसे सफेद स्थान का उपभोग करने और नई लाइन तक पढ़ने के रूप में दस्तावेज किया गया है। –

1

मैं जानता हूँ कि यह पहले से ही उत्तर दिया गया है, लेकिन यह मेरी कार्यान्वयन था:

func flush (reader *bufio.Reader) { 
    var i int 
    for i = 0; i < reader.Buffered(); i++ { 
     reader.ReadByte() 
    } 
} 

यह, हर स्थिति में काम करना चाहिए लोगों को जहां "stdin.ReadString ('\ n')" नहीं किया जा सकता सहित उपयोग किया गया।

1

क्या पुराना सवाल उठाना बुरा है?

मैं fmt.Scanln का उपयोग करना पसंद करता हूं क्योंकि ए) इसे किसी अन्य लाइब्रेरी (उदा। पाठक) और बी आयात करने की आवश्यकता नहीं है) इसमें लूप के लिए स्पष्ट शामिल नहीं है।

func someFunc() { 
    fmt.Printf("Please enter an integer: ") 

    // Read in an integer 
    var i int 
    _, err := fmt.Scanln(&i) 
    if err != nil { 
      fmt.Printf("Error: %s", err.Error()) 

      // If int read fails, read as string and forget 
      var discard string 
      fmt.Scanln(&discard) 
      return 
    } 
    fmt.Printf("Input contained %d", i) 
} 

हालांकि, ऐसा लगता है कि वहां एक और अधिक सुरुचिपूर्ण समाधान होना चाहिए। विशेष रूप से fmt.Scanln के मामले में यह अजीब लगता है कि पढ़ना "लाइन स्कैनिंग" की बजाय पहले गैर-संख्या बाइट के बाद बंद हो जाता है।

1

मैं उपयोगकर्ता इनपुट प्राप्त करने के लिए एक समान समस्या में भाग गया लेकिन इसे थोड़ा अलग तरीके से हल किया। किसी और मामले में किसी को धागा करने के लिए जोड़ा जा रहा है इस उपयोगी पाता है: यह वापस ऊपर खुदाई के लिए

package main 

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

// Get first word from stdin 
func getFirstWord() (string) { 
    input := bufio.NewScanner(os.Stdin) 
    input.Scan() 
    ans := strings.Fields(input.Text()) 

    if len(ans) == 0 { 
     return "" 
    } else { 
     return ans[0] 
    } 
} 

func main() { 
    fmt.Printf("Would you like to play a game?\n> ") 
    ans := getFirstWord() 
    fmt.Printf("Your answer: %s\n", ans) 
} 
0

क्षमा करें, लेकिन मैं आज में पड़ गए और नए मानक पुस्तकालय कार्यक्षमता का उपयोग करके मौजूदा जवाब पर सुधार करने के लिए करना चाहता था।

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

func discardBuffer(r *bufio.Reader) { 
    r.Discard(r.Buffered()) 
} 

stdin := bufio.NewReader(os.Stdin) 
var i int 
for true { 
    if _, err := fmt.Fscanln(stdin, &i); err != nil { 
     discardBuffer(stdin) 
     // Handle error, display message, etc. 
     continue 
    } 
    // Do your other value checks and validations 
    break 
} 

मूल विचार हमेशा अपने पढ़ने को stdin से बफर करना है। स्कैनिंग करते समय आपको कोई त्रुटि आती है, तो बस बफर सामग्री को छोड़ दें। इस तरह आप अपने अगले स्कैन के लिए एक खाली बफर से शुरू करते हैं।

वैकल्पिक रूप से, आप स्कैन करने से पहले बफर को त्याग सकते हैं, इसलिए पहले उपयोगकर्ता द्वारा किसी भी भटक इनपुट को उठाया नहीं जाएगा।

func fscanln(r *bufio.Reader, a ...interface{}) error { 
    r.Discard(r.Buffered()) 
    _, err := fmt.Fscanln(r, a...) 
    return err 
} 

stdin := bufio.NewReader(os.Stdin) 
var i int 
if err := fscanln(stdin, &i); err != nil { 
    // Handle error 
}