0
votes

I'm trying to build a very basic console inputs for a program using a loop. However, when user inputs something else than an integer, the error message triggers as many times as there are characters in the input string (including newline).

I've tried Scan(), Scanln(), as well as bufio.NewReader() with string parsing, as well as using continue after Println(). All produce the same result.

var threads int

func main() {
    fmt.Println("Enter number of threads:")
    for {
        _, err := fmt.Scanln(&threads)
        if err != nil {
            fmt.Println("Enter a valid number")
        } else {
            break
        }
    }
}

User inputs:

asd

Expected result:

Program: Enter a valid number

Actual result:

Program: Enter a valid number

Program: Enter a valid number

Program: Enter a valid number

Program: Enter a valid number

1
Have you checked what the error returned actually is? You're checking if it's nil but you're not examining the value.Adrian
Yes, I checked them. For characters it was "Expected integer" and for newline "Unexpected newline". This is predictable but what I still don't understand is why it triggers the iferr statement as true multiple times before proceeding.Inhert

1 Answers

1
votes

fmt.Scanln(&threads) throws an error because your first char is already not a valid int, thus there are sd\n still remaining in stdin buffer, this would be my explanation for additional three errors. To avoid this you could just read to string and then use int, err := strconv.Atoi(string) like in code below. Note hereby that fmt.Scan or fmt.Scanln split your userinput until the next space, which is probably not perfect for your usecase. Check out How to read input from console line for some insight in how to choose suiting your usecase.

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var s string
    var i int
    fmt.Println("Enter number of threads:")
    for {
        _, err := fmt.Scan(&s)
        i, err = strconv.Atoi(s)
        if err != nil {
            fmt.Println("Enter a valid number")
        } else {
            fmt.Println("Got: " + strconv.Itoa(i))
            break
        }
    }
    //Todo
}