Rune instead of string in Scanln

Below is the code for reading the input from console

var message string
fmt.Scanln(&message)

But I wanted to try same with rune, which is unicode of byte

var input []rune
fmt.Scanln(input)

As per my C/C++ knowledge, where an array’s reference can be passed through its name , I thought it would work in case of rune

But surprisingly the program passes Scanln in case of rune without even taking console input

What is that am doing wrong? Or it cannot be done ? Or it requires type casting to string ?

The fmt doc says near the end of the Overview section: “All arguments to be scanned must be either pointers to basic types or implementations of the Scanner interface.” . A slice is not a basic type, and neither does it implement the Scanner interface.

Also be aware that fmt.Scanln returns an error object. It is always a good idea to check the error value that a function call returns. Checking the error message of fmt.Scanln(input) yields, “Error: type not a pointer: []int32”. (Side note: technically, a rune is an int32.)

Unfortunately, fmt.Scanln(&input) does not help as fmt.Scanln can only scan []byte. But a for..range loop over a string iterates over the string rune-by-rune (rather than byte-by-byte), you could scan into a string and then get the runes out of the string like so:

package main

import (
	"fmt"
	"io"
	"log"
)

func main() {
	var s string
	_, err := fmt.Scanln(&s)
	if err != nil && err != io.EOF {
		log.Fatal("Error: ", err)
	}
	for _, r := range s {
		fmt.Print("rune: ", r, ",")
	}
	fmt.Println()
}
3 Likes

Thanks. that answers my question

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.