Entrada de Datos. Go
SOLUCIONARIO
Entrada de Datos. Go
2026-07-12
Por
Occam's Razor

package main

import (
    "fmt"

)

func main(){
     var n int
     var t int
     var a[10] int

     fmt.Print ("Introduce 2 numeros separados por espacios ? ")
     fmt.Scanf ("%d %d", &n, &t)
     fmt.Printf ("Has introducido %d y %d\n", n, t)
     fmt.Println ("Introduce 10 numeros separados por espacios ? ")

     for i:= 0; i < 10; i++ {
         fmt.Scanf ("%d", &a[i])
     }
     fmt.Println ("Has introducido : ");
     fmt.Println (a[0:9])
     for i:= 0; i < 10; i++ {
         fmt.Print (a[i], " ")
     }
     fmt.Println()
}

La versión Go, salvando las diferencias intrínsecas de sintaxis, es idéntica a la versión en C. Go ofrece una función Scanf que funciona de la misma forma que C para este ejemplo.

El uso de esta solución hace que no nos tengamos de preocupar de los retornos de carro en la entrada del usuario, sin embargo, al igual que sucedía con la versión C no nos permite validar fácilmente los datos de entrada y hace que nuestro programa parezca código C en lugar de código Go.

SABÍAS QUE?

Además de Scanf, el paquete fmt nos ofrece los métodos Scan (valores separados solo por espacios) y Scanln que lee una línea entera. Todas ellas devuelve como segundo parámetro un error que se puede utilizar para detectar errores. Scan para de procesar el texto cuando encuentra el primer error, así que es una buena práctica comprobar también el primer parámetro (número de valores convertidos) para determinar donde se produjo el error:

n, err := fmt.Scanf("%d %d", &a, &b)

if err != nil {
    fmt.Println("Error:", err)
    return
}

if n != 2 {
    fmt.Println("No se leyeron los dos números")
    return
}
 

Como sucede con la mayoría de lenguajes que ya hemos visto, si queremos tener un control más fino sobre la la entrada de usuario podemos leerla como una cadena de caracteres y luego parsear esa cadena comprobando la validez de cada dato.

La forma de hacer esto en Go es utilizando un objeto Reader que nos permite leer data de distintas fuentes, entre las que está incluida la entrada estándar. Sin embargo, en muchos casos nos interesa usar bufio.NewReader que crea un objeto Reader pero incluyendo buffering y algunos métodos que nos vendrán muy bien.

SOY NOVATO

Los objetos Reader nos permiten leer datos del teclado stdin, un fichero, la red o desde una cadena de caracteres en memoria, lo que nos ofrece una gran versatilidad.

 

El siguiente código utiliza este objeto para leer una cadena de caracteres de la consola.

reader := bufio.NewReader(os.Stdin)
input, err = reader.ReadString('\n')
input = strings.TrimSpace(input)

La primera línea crea nuestro objeto Reader para leer el teclado. La siguiente línea nos permite leer una cadena de caracteres hasta que se encuentre el caracter \n (similar a fgets en C). Este método ReadString es el que nos permite leer la línea de texto entera para procesarla posteriormente. Observad que este método incluye el retorno de carro en la cadena leída, el cual podemos eliminar con el método strings.TrimSpace.

SOY NOVATO

A diferencia de la mayoría de lenguajes modernos Go no utiliza excepciones para devolver errores normales. En su lugar las funciones devuelven dos valores. Uno conteniendo el resultado (si la ejecución fue correcta) y otro conteniendo el valor del error. El error devuelto será nil si no ha ocurrido ningún error o no nil en caso contrario. En este último caso, ese segundo valor retornado continene una descripción del error.

Una vez que tenemos la cadena de caracteres, podemos utilizar los métodos de la clase strconv para convertir nuestra cadena en valores numéricos. Estos son los métodos que nos interesan:

  • strconv.ParseInt (s string, base int, bitsize int convierte cadenas a entero, pero permitiéndonos convertir valores expresados en diferentes bases y producir enteros del tamaño de bits indicados (8, 16, 32, 63).
  • strconv.Atoi (s string) conversión de cadena a entero. Realmente es un wrapper al rededor de ParseInt, para base 10 y 64 bits.
  • strconv.ParseFloat (s string, bitsize int) convierte cadenas en valores decimales, permitiéndonos decidir si queremos float32 o float64.

Si queremos poder leer varios valores en una sola línea, debemos partir la línea como sucede en otros lenguajes. El siguiente código muestra un ejemplo de como hacer esto.

    reader := bufio.NewReader(os.Stdin)

    fmt.Print("Introduce 3 numeros: ")
    line, _ := reader.ReadString('\n')
    line = strings.TrimSpace(line)

    fields := strings.Fields(line)

    var numbers []int
    for _, field := range fields {
        n, err := strconv.Atoi(field)
        if err != nil {
            fmt.Printf("%q is not a valid integer\n", field)
            return
        }
        numbers = append(numbers, n)
    }

    fmt.Println(numbers)

Este código utiliza el método strings.Fields que divide la cadena que recibe como parámetro en campos, utilizando espacios, tabuladores y saltos de línea como separadores, y los almacena en una slice de cadenas de texto en el que cada elemento contiene una de las palabras encontradas.

Una vez que tenemos el slice, solo hay que recorrerlo de la forma que ya sabe, para convertir cada uno de los elementos a su representación numérica y almacenarlos en un nuevo array, ahora numérico, utilizando el método append.

RESUMEN

  • Podemos leer datos en nuestro programa usando fmt.Scanf o un objeto Reader.
  • Para poder validar los datos introducidos por el usuario, debemos leer la entrada como una cadena de caracteres y procesarla para extraer la información que nos interesa. Esto se hace mas fácilmente con un objeto Reader y los métodos ReadString, ParseInt, ParseFloat y Atoi.
  • Si queremos leer varios datos en una sola línea es necesario trocear la línea y luego procesar cada uno de los datos por separados. O utilizar Scanf

SOBRE Occam's Razor
Somos una revista libre que intenta explicar de forma sencilla conceptos tecnológicos y científicos de los que no podemos escapar. Al final, todo es más fácil de lo que parece!

 
Tu publicidad aquí :)