Why is this printing twice?

Hello everyone! I’m really new to Go, so I thought what better way to learn the language but by creating a guess the number game!

Its going fairly good, parses user input…but there’s something I just can’t understand.
I have this code:

package main

import (
	"fmt"
	"math/rand"
	"strconv"
)

func randRangeInt(min int, max int) int {
	return min + rand.Intn(max-min)
}

func validateInput(input string) (int) {
	result, err := strconv.Atoi(input)

	if err != nil {
		return -1
	} else {
		return result
	}
}

func main() {
	var secret int = randRangeInt(0, 100)
	var userGuess string

	fmt.Println("I'm thinking of a number between 0 and 100. Try guessing it:")

	fmt.Scanf("%s", &userGuess)

	result := validateInput(userGuess)

	for result < 0 {
		fmt.Println("Try again. Between 0 and 100.")
		fmt.Scanf("%s", &userGuess)
		result = validateInput(userGuess)
	}

	if result > -1 {
		switch {
		case result < secret:
			fmt.Println("Your guess is too low")
		case result > secret:
			fmt.Println("Your guess is too high")
		case result == secret:
			fmt.Println("That's it!")
		}
	} else {
		panic("Something went wrong")
	}
}

and in the main function theres a check, if the result returned from the validateInput functinon is less than 0 (meaning there was an error converting it), that’ll prompt the user again, to input something else. And here’s the problem* I’m having. When I intentionally input something that’s not a number, it prompts twice, like:

Can someone tell me why this is?

I know it might be a dumb question, but like I said, I just started using go, and this is quite confusing. Thanks for anyone who’s open to help :smiley:

Edit 1: I’m not particularly interested in better error handling or anything like that (altho it’s much appreciated). I just want to know why it prints twice.

I can’t reproduce your problem.

 $ go run main.go
I'm thinking of a number between 0 and 100. Try guessing it:
-7
Try again. Between 0 and 100.
-100
Try again. Between 0 and 100.
88
Your guess is too high

And from a quick look at your code I can’t immediately see why it would print the prompt twice.

1 Like

Thats strange. This is all the code i have, so i have no idea whats going in if you cant reproduce it. Maybe my powershell is acting up

1 Like

In order to reproduce your result as closely as possible, I entered f as my first guess, exactly as you did.

% go run ./main.go
I'm thinking of a number between 0 and 100. Try guessing it:
f
Try again. Between 0 and 100.
50
Your guess is too low
%

Sorry, this did not reproduce the same result as you got.

I also ran the program using valid numbers as input, and again each response prompt appeared once, rather than twice. This testing included guessing the correct number.

I got the same results as Aronk112. I guess it is validating the enter key too so maybe you need to flush the stdin buffer. Try fmt.Scanf("%s\r ", &userGuess). Also I am using Windows…

2 Likes

Hmmm … Very interesting.

My system is a MacBook Air with Ventura, and the testing was performed via the Terminal window.

That was it. My guess is that Scanf kept a reference to the enter press (or it’s still in memory as it gets compiled? i have no idea how go does these things. its inner workings are really different from what I’m used to, so sorry if I’m talking gibberish and English is not my native) after ‘go run ./main.go’. By changing the first fmt.Scanf("%s", &userGuess) to fmt.Scanf("%s\r", &userGuess) it works. Thanks for the suggestion!

Edit3(4?) I tested it with a preset value to check against, and it still prints twice, so it can’t be the enter thats pressed to validate the f character (as in my example)

Maybe it has to do with how windows powershell works. You’re probably using zsh if you’re on mac?

1 Like

Yes, I was using zsh on the Mac.