質問

私は)(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
}
役に立ちましたか?

解決

あなたの更新されたコードは、行番号なしでコンパイルする方がはるかに簡単だったが、それは、パッケージおよびインポート文が欠落していました。

あなたのコードを見て、私はいくつかのことに気づきました。ここにあなたのコードの私の改訂版だ。

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()のための任意の入力ファイルを使用する場合があります、だけでなくStdinscanf()は、パラメータとしてio.Readerを取ります。

あなたは書きました:nums := new(vector.IntVector)type IntVector []int。これはnums名前整数スライスの参照を割り当て、ゼロに初期化し、その後new()関数は、整数スライスの参照を割り当て、ゼロに初期化し、その後numsに割り当てます。私が書いた:var nums vector.IntVectorを、単にnums名前整数スライスの参照を割り当て、それをゼロに初期化することにより、冗長性を回避する

あなたはゼロ値に変換された無効な入力を意味err、用strconv.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

他のヒント

それは他のもののために使用することができますが、

、スキャナパッケージは、囲碁プログラムテキストをスキャンするように設計されています。 INTS(-123)、文字数( 'C')、文字列( "STR")などのGo言語トークンタイプです。

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()
    }
}

この例では、常に時のラインを読み込み、文字列として行全体を返します。あなたはそれから特定の値を解析したい場合でします。

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 
}

私の答えの一つにコメントでは、あなたが言っます:

  

言語仕様から:「とき   メモリは、値を格納するために割り当てられ、   宣言を通して、または()のいずれかにします   または新しい()の呼び出し、および明示的な   初期化は、メモリが設けられています。   「デフォルトの初期化を与えています。   その後)(新規のポイントは何ですか?

私たちが実行している場合:

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は、整数値を格納するメモリを割り当て、値をゼロに初期化します。宣言var j *intは、整数値へのポインタを格納するためにメモリを割り当て、ゼロ(NULLポインタ)へのポインタを初期化します。いかなるメモリは、整数値を格納するために割り当てられません。

:私たちは次のようにプログラムの出力を参照してください
i (a value) =  0 ; j (a pointer) =  <nil>

組み込み関数newは型Tを取り、型*Tの値を返します。メモリはゼロ値に初期化されます。ステートメントj = new(int)は、整数値を格納するメモリを割り当て、値をゼロに初期化し、それがjで、この整数値へのポインタを格納します。

:私たちは次のようにプログラムの出力を参照してください
i (a value) =  0 ; j (a pointer) =  0x7fcf913a90f0 ; *j (a value) =  0

ゴーの最新のリリース(2010-05-27)はfmtパッケージに二つの機能を追加しました:<のhref = "http://golang.org/pkg/fmt/#Scan" のrel = "nofollowをnoreferrer" > Scan() Scanln() に。彼らは、任意のパターン文字列を取ることはありません。 Cのように、代わりに、引数の型をチェックします。

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())
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top