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.
Además de
Scanf, el paquetefmtnos ofrece los métodosScan(valores separados solo por espacios) yScanlnque lee una línea entera. Todas ellas devuelve como segundo parámetro un error que se puede utilizar para detectar errores.Scanpara 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.
Los objetos
Readernos permiten leer datos del tecladostdin, 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.
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á
nilsi no ha ocurrido ningún error o nonilen 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 intconvierte 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 deParseInt, para base 10 y 64 bits.strconv.ParseFloat (s string, bitsize int)convierte cadenas en valores decimales, permitiéndonos decidir si queremosfloat32ofloat64.
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.Scanfo un objetoReader. - 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
Readery los métodosReadString,ParseInt,ParseFloatyAtoi. - 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
■
