Leer un número entero de la entrada estándar

85

¿Cómo utilizo la fmt.Scanffunción en Go para obtener una entrada entera de la entrada estándar?

Si esto no se puede hacer usando fmt.Scanf, ¿cuál es la mejor manera de leer un solo entero?

yasith
fuente

Respuestas:

132

http://golang.org/pkg/fmt/#Scanf

Todas las bibliotecas incluidas en Go están bien documentadas.

Dicho eso, creo

func main() {
    var i int
    _, err := fmt.Scanf("%d", &i)
}

Hace el truco

cthom06
fuente
fmt.Scanf tardó aproximadamente un minuto en escanear 1 millón de enteros.
robert king
@robertking intenta usar un bufio en su lugar. Es un ejemplo simple.
cthom06
Salud. Bufio es rápido.
robert king
5
¿Puede explicarnos por qué debemos entrar &iy no solo icomo en fmt.Printf("%v", i)?
Zeynel
6
@Zeynel Porque los parámetros se pasan por valor en Go. ies solo el valor entero en i, &ies un puntero a i.
cthom06
48

Una alternativa que puede ser un poco más concisa es simplemente usar fmt.Scan:

package main

import "fmt"

func main() {
    var i int
    fmt.Scan(&i)
    fmt.Println("read number", i, "from stdin")
}

Esto usa la reflexión sobre el tipo de argumento para descubrir cómo se debe analizar la entrada.

http://golang.org/pkg/fmt/#Scan

iainmcgin
fuente
4

Aquí está mi método "Fast IO" para leer enteros positivos. Podría mejorarse con cambios de bits y distribuyendo la memoria por adelantado.

package main

import (
    "io/ioutil"
    "bufio"
    "os"
    "strconv"
)


func main() {
    out := bufio.NewWriter(os.Stdout)
    ints := getInts()
    var T int64
    T, ints = ints[0], ints[1:]
    ..
    out.WriteString(strconv.Itoa(my_num) + "\n")
    out.Flush()
    }
}

func getInts() []int64 {
    //assumes POSITIVE INTEGERS. Check v for '-' if you have negative.
    var buf []byte
    buf, _ = ioutil.ReadAll(os.Stdin)
    var ints []int64
    num := int64(0)
    found := false
    for _, v := range buf {
        if '0' <= v && v <= '9' {
            num = 10*num + int64(v - '0') //could use bitshifting here.
            found = true
        } else if found {
            ints = append(ints, num)
            found = false
            num = 0
        }
    }
    if found {
        ints = append(ints, num)
        found = false
        num = 0
    }
    return ints
}
Robert King
fuente
3

Golang fmt.Scan es más simple que Golang fmt.Scanf (que es más simple que Clang scanf)

Si fmt.Scan errores, es decir, si no es nulo, iniciar sesión y volver

1 Lea una sola variable:

import (
    "fmt"
    "log"
)

var i int
if    _, err := fmt.Scan(&i);    err != nil {
    log.Print("  Scan for i failed, due to ", err)
    return
}

fmt.Println(i)

2 Lea múltiples variables:

import (
    "fmt"
    "log"
)

var i, j, k int  
if    _, err := fmt.Scan(&i, &j, &k);    err != nil {
    log.Print("  Scan for i, j & k failed, due to ", err)
    return
}

fmt.Println(i, j, k)

La mejor de las suertes

Ejemplo de: http://www.sortedinf.com/?q=golang-in-1-hour

Manohar Reddy Poreddy
fuente
0

Puede utilizar fmt.Scanfcon un especificador de formato. El especificador de formato para el entero es% d. Entonces puede usar la entrada estándar como a continuación.

func main() {
    var someVar int
    fmt.Scanf("%d", &someVar)
}

o de lo contrario puede usar fmt.Scano fmt.Scanlncomo se muestra a continuación.

func main() {
   var someVar int
   fmt.Scanln(&someVar)
}
Jacinto de Kaveen
fuente