2010-03-10 14 views
6

के समकक्ष के लिए खोज रहे हैं मैं scanf() के गो समकक्ष की तलाश में हूं। मैं निम्नलिखित कोड के साथ करने की कोशिश की:स्कैनफ़

1 package main 
    2 
    3 import (
    4  "scanner" 
    5  "os" 
    6  "fmt" 
    7) 
    8 
    9 func main() { 
10  var s scanner.Scanner 
11  s.Init(os.Stdin) 
12  s.Mode = scanner.ScanInts 
13  tok := s.Scan() 
14  for tok != scanner.EOF { 
15   fmt.Printf("%d ", tok) 
16   tok = s.Scan() 
17  } 
18  fmt.Println() 
19 } 

मैं पूर्णांकों की एक पंक्ति के साथ एक पाठ से इनपुट के साथ इसे चलाने के। लेकिन यह हमेशा उत्पादन -3 -3 ...

और कैसे एक स्ट्रिंग और कुछ पूर्णांकों से बना एक लाइन स्कैन करने के लिए? जब भी कोई नया डेटा प्रकार मिलता है तो मोड को बदलना?

पैकेज प्रलेखन:

पैकेज स्कैनर UTF-8 इनकोडिंग पाठ के लिए

एक सामान्य प्रयोजन स्कैनर।

लेकिन ऐसा लगता है कि स्कैनर सामान्य उपयोग के लिए नहीं है।

अपडेट किया गया कोड:

func main() { 
    n := scanf() 
    fmt.Println(n) 
    fmt.Println(len(n)) 
} 

func scanf() []int { 
    nums := new(vector.IntVector) 
    reader := bufio.NewReader(os.Stdin) 
    str, err := reader.ReadString('\n') 
    for err != os.EOF { 
     fields := strings.Fields(str) 
     for _, f := range fields { 
      i, _ := strconv.Atoi(f) 
      nums.Push(i) 
     } 
     str, err = reader.ReadString('\n') 
    } 
    r := make([]int, nums.Len()) 
    for i := 0; i < nums.Len(); i++ { 
     r[i] = nums.At(i) 
    } 
    return r 
} 

उन्नत संस्करण:

package main 

import (
    "bufio" 
    "os" 
    "io" 
    "fmt" 
    "strings" 
    "strconv" 
    "container/vector" 
) 

func main() { 
    n := fscanf(os.Stdin) 
    fmt.Println(len(n), n) 
} 

func fscanf(in io.Reader) []int { 
    var nums vector.IntVector 
    reader := bufio.NewReader(in) 
    str, err := reader.ReadString('\n') 
    for err != os.EOF { 
     fields := strings.Fields(str) 
     for _, f := range fields { 
      if i, err := strconv.Atoi(f); err == nil { 
       nums.Push(i) 
      } 
     } 
     str, err = reader.ReadString('\n') 
    } 
    return nums 
} 
+2

अच्छे उत्तर पाने के लिए, आपको अपने प्रश्नों को उत्तर देने में आसान बनाना होगा। उदाहरण के लिए, कोड जिसे आसानी से कॉपी, पेस्ट और संकलित किया जा सकता है। जाओ शिकायत लाइन नंबर स्वीकार नहीं करता है; उन्हें अपने नमूना कोड में न रखें। – peterSO

+2

शायद मूल रूप से पोस्ट होने पर यह अस्तित्व में नहीं था, लेकिन जाओ fmt.Scanf है जो सी स्कैनफ की तरह काम करता है जैसे stdin: var number int fmt.Scanf ("% d", और संख्या) – Myforwik

+0

ओह मेरे भगवान! मैं stdin से एक अच्छा पाठक पाने के लिए घंटों के लिए कोशिश कर रहा हूँ। मैन, मैं बस यह नहीं समझ सका कि इसे कैसे लिखना है। अपना कोड –

उत्तर

4

आपका अपडेट किया गया कोड ज्यादा लाइन नंबर के बिना संकलित करने के लिए आसान था, लेकिन यह पैकेज और आयात बयान याद आ रही थी।

अपने कोड को देखते हुए, मैंने कुछ चीजें देखीं। यहां आपके कोड का मेरा संशोधित संस्करण है।

package main 

import (
    "bufio" 
    "fmt" 
    "io" 
    "os" 
    "strconv" 
    "strings" 
    "container/vector" 
) 

func main() { 
    n := scanf(os.Stdin) 
    fmt.Println() 
    fmt.Println(len(n), n) 
} 

func scanf(in io.Reader) []int { 
    var nums vector.IntVector 
    rd := bufio.NewReader(os.Stdin) 
    str, err := rd.ReadString('\n') 
    for err != os.EOF { 
     fields := strings.Fields(str) 
     for _, f := range fields { 
      if i, err := strconv.Atoi(f); err == nil { 
       nums.Push(i) 
      } 
     } 
     str, err = rd.ReadString('\n') 
    } 
    return nums 
} 

मैं scanf() के लिए किसी भी इनपुट फ़ाइल का उपयोग करने, चाहते हो सकता है न सिर्फ Stdin; scanf() एक पैरामीटर के रूप में io.Reader लेता है।

आप ने लिखा है: nums := new(vector.IntVector), जहां type IntVector []int। यह एक पूर्णांक टुकड़ा संदर्भ nums नामित आवंटित और शून्य करने के लिए यह initializes, तो new() समारोह एक पूर्णांक टुकड़ा संदर्भ आवंटित और शून्य करने के लिए यह initializes, और फिर nums करने के लिए इसे प्रदान करती है। मैंने लिखा: var nums vector.IntVector, जो nums नामक एक पूर्णांक टुकड़ा संदर्भ आवंटित करके और इसे शून्य पर प्रारंभ करके अनावश्यकता से बचाता है।

आपने errstrconv.Atoi() के लिए मूल्य की जांच नहीं की, जिसका अर्थ है कि अमान्य इनपुट शून्य मान में परिवर्तित किया गया था; मैं इसे छोड़ देता हूँ।

एक नया टुकड़ा करने के लिए वेक्टर से कॉपी और टुकड़ा लौटने के लिए, आप ने लिखा है:

r := make([]int, nums.Len()) 
for i := 0; i < nums.Len(); i++ { 
    r[i] = nums.At(i) 
} 
return r 

सबसे पहले, मैं बस की जगह है कि एक समान, IntVector.Data() विधि के साथ: return nums.Data()। फिर, मैंने इस तथ्य का लाभ उठाया कि type IntVector []int और इसे स्थानांतरित करके आवंटन और प्रतिलिपि से बचा: return nums

+0

पोस्ट करने के लिए बहुत बहुत धन्यवाद! 1. भाषा विशिष्टता से: "जब किसी मान को स्टोर करने के लिए स्मृति आवंटित की जाती है, या तो घोषणा के माध्यम से या() या नया() कॉल करें, और कोई स्पष्ट प्रारंभिकरण प्रदान नहीं किया जाता है, तो स्मृति को डिफ़ॉल्ट प्रारंभिकरण दिया जाता है"। तो नया() का क्या मतलब है? 2. मैंने पहली बार "इंटेक्टर [] int" टाइप किया। जाओ सी ++ से बहुत अलग है। और जैसा कि IntVector int int [] है, फ़ंक्शन डेटा() अनावश्यक है? –

0

हालांकि यह अन्य बातों के लिए इस्तेमाल किया जा सकता, स्कैनर पैकेज जाओ कार्यक्रम पाठ स्कैन करने के लिए बनाया गया है। इंट्स (-123), चार्स ('सी'), स्ट्रिंग्स ("स्ट्र") इत्यादि गो भाषा टोकन प्रकार हैं।

package main 

import (
    "fmt" 
    "os" 
    "scanner" 
    "strconv" 
) 

func main() { 
    var s scanner.Scanner 
    s.Init(os.Stdin) 
    s.Error = func(s *scanner.Scanner, msg string) { fmt.Println("scan error", msg) } 
    s.Mode = scanner.ScanInts | scanner.ScanStrings | scanner.ScanRawStrings 
    for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { 
     txt := s.TokenText() 
     fmt.Print("token:", tok, "text:", txt) 
     switch tok { 
     case scanner.Int: 
      si, err := strconv.Atoi64(txt) 
      if err == nil { 
       fmt.Print(" integer: ", si) 
      } 
     case scanner.String, scanner.RawString: 
      fmt.Print(" string: ", txt) 
     default: 
      if tok >= 0 { 
       fmt.Print(" unicode: ", "rune = ", tok) 
      } else { 
       fmt.Print(" ERROR") 
      } 
     } 
     fmt.Println() 
    } 
} 
0

यह उदाहरण हमेशा एक समय में एक लाइन में पढ़ता है और एक स्ट्रिंग के रूप पूरी पंक्ति देता है। यदि आप इससे विशिष्ट मूल्यों का विश्लेषण करना चाहते हैं तो आप कर सकते हैं।

package main 

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

func main() { 
    value := Input("Please enter a value: ") 
    trimmed := strings.TrimSpace(value) 
    fmt.Printf("Hello %s!\n", trimmed) 
} 

func Input(str string) string { 
     print(str) 
     reader := bufio.NewReader(os.Stdin) 
     input, _ := reader.ReadString('\n') 
     return input 
} 
0

अपने जवाब में से एक के लिए एक टिप्पणी में, आप ने कहा:

भाषा विशिष्टता से: " स्मृति या तो एक घोषणा के माध्यम से एक मूल्य, की दुकान या (बनाने) या नया करने के लिए आवंटित किया जाता है() कॉल, और कोई स्पष्ट प्रारंभिकता प्रदान की जाती है, स्मृति को डिफ़ॉल्ट प्रारंभिकता दी जाती है "। फिर नया() का क्या मतलब है?

अगर हम चलाएँ:

package main 

import ("fmt") 

func main() { 
    var i int 
    var j *int 
    fmt.Println("i (a value) = ", i, "; j (a pointer) = ", j) 
    j = new(int) 
    fmt.Println("i (a value) = ", i, "; j (a pointer) = ", j, "; *j (a value) = ", *j) 
} 

घोषणा var i int एक पूर्णांक मान संग्रहीत स्मृति आवंटित करता है और शून्य करने के लिए मूल्य initializes। घोषणा var j *int एक सूचक को एक पूर्णांक मान में संग्रहीत करने के लिए स्मृति आवंटित करता है और सूचक को शून्य (एक शून्य सूचक) में प्रारंभ करता है; एक पूर्णांक मूल्य को स्टोर करने के लिए कोई स्मृति आवंटित नहीं की जाती है।

i (a value) = 0 ; j (a pointer) = <nil> 

में निर्मित समारोह new एक प्रकार T लेता है और प्रकार *T का एक मान देता है: हम कार्यक्रम उत्पादन के लिए इसी तरह देखते हैं। स्मृति शून्य मानों के लिए शुरू किया गया है। कथन j = new(int) एक पूर्णांक मान को संग्रहीत करने के लिए स्मृति आवंटित करता है और मान को शून्य में प्रारंभ करता है, फिर यह जे में इस पूर्णांक मान के लिए एक सूचक को संग्रहीत करता है।

i (a value) = 0 ; j (a pointer) = 0x7fcf913a90f0 ; *j (a value) = 0 
+0

क्या नया() ढेर या ढेर आवंटन से संबंधित है? –

+0

प्रति-थ्रेड कैश की निःशुल्क सूचियों से छोटी वस्तुओं को आवंटित किया जाता है।बड़ी वस्तुओं (> 32 केबी) सीधे ढेर से आवंटित की जाती हैं। – peterSO

0

जाओ की नवीनतम रिलीज (2010-05-27) fmt पैकेज के लिए दो कार्य जोड़ा गया है: Scan() और Scanln() हम कार्यक्रम उत्पादन के लिए इसी तरह देखते हैं। वे कोई पैटर्न स्ट्रिंग नहीं लेते हैं। सी में की तरह, लेकिन इसके बजाय तर्क के प्रकार की जांच करता है।

package main 

import (
    "fmt" 
    "os" 
    "container/vector" 
) 

func main() { 
    numbers := new(vector.IntVector) 
    var number int 
    n, err := fmt.Scan(os.Stdin, &number) 
    for n == 1 && err == nil { 
     numbers.Push(number) 
     n, err = fmt.Scan(os.Stdin, &number) 
    } 
    fmt.Printf("%v\n", numbers.Data()) 
} 
+0

इस समय, 2 जून, 2010 को, एफएमटी पैकेज स्कैन सुविधा बहुत ही लगातार अपडेट और पर्याप्त संशोधन के साथ एक अधूरा कार्यान्वयन है। – peterSO

+0

हां। मैं अगली रिलीज पर उत्तर अपडेट करने के लिए याद रखने की कोशिश करूंगा। –

संबंधित मुद्दे