I'm trying to validate the user input. If the user inputs an integer number it works like expected. However, if the user inputs a non-integer string, the variable userTickets gets assigned value 0, but prints Try again! It must be more than zero: many times. To be exact, it prints len(input) times and I don't understand why.
Also tried achieving desired result using fmt.Scanf("%d", &usertickets) but got an identical result.
Why does it behave this way and how can I write a workaround for it?
package main
import "fmt"
func main() {
var remainingTickets uint = 50
var userTickets uint
fmt.Print("Enter the number of tickets you want to purchase: ")
fmt.Scan(&userTickets)
for userTickets > remainingTickets {
fmt.Printf("We only have %v tickets available!\n", remainingTickets)
fmt.Print("Try again! Enter the number of tickets: ")
fmt.Scan(&userTickets)
}
for userTickets == 0 {
fmt.Print("Try again! It must be more than zero: ")
fmt.Scan(&userTickets)
}
fmt.Printf("Remaining tickets: %v\n", remainingTickets-userTickets)
}
CodePudding user response:
Scan is able to determine that the input isn't numeric without reading the entire contents of stdin. This is why you validation logic loops for len(input) when non-numeric. While you can use a Scanner as well (and people do recommend that approach), below is an approach similar to yours. Note that all validation checking is done within a single "for" loop as well:
package main
import (
"fmt"
"strconv"
)
func main() {
var remainingTickets uint64 = 50
fmt.Print("Enter the number of tickets you want to purchase: ")
for {
var userTickets string
fmt.Scanln(&userTickets)
// parse to make sure we get a positive (unsigned) integer
u64, err := strconv.ParseUint(userTickets,10,64)
// make sure it's a postive integer and not equal to zero
if err != nil || u64==0{
fmt.Print("Try again! You must enter a number greater than zero: ")
continue
}
// check to make sure we have enough tickets left
if u64 > remainingTickets {
fmt.Printf("We only have %v tickets available!\n", remainingTickets)
fmt.Print("Try again! Enter the number of tickets: ")
continue
}
// update remaining tickets
remainingTickets -= u64
break
}
fmt.Printf("Remaining tickets: %d\n", remainingTickets)
}
