Вот простая программа, использующая bufio.Scanner и fmt.Scanln, которая работает должным образом:
scanner := bufio.NewScanner(os.Stdin)
var s string
fmt.Println("Enter a string:")
scanner.Scan()
s = scanner.Text()
fmt.Printf("You entered: %q\n\n", s)
var i int
fmt.Println("Enter an int:")
fmt.Scanln(&i)
fmt.Printf("You entered: %d\n", i)
Вот результат программы (текст в скобках [] - ввод с клавиатуры)
Enter a string:
[mary had a little lamb]
You entered: "mary had a little lamb"
Enter an int:
[42]
You entered: 42
Теперь вместо использования стандартного стандартного ввода-вывода давайте использовать канал для перенаправления ввода из строки, а не с клавиатуры.
readStdin, writeStdin, err := os.Pipe()
if err != nil {
fmt.Println("Pipe Error:", err)
return
}
os.Stdin = readStdin
writeStdin.WriteString("mary had a little lamb\n42\n")
scanner := bufio.NewScanner(os.Stdin)
var s string
fmt.Println("Enter a string:")
scanner.Scan()
s = scanner.Text()
fmt.Printf("You entered: %q\n\n", s)
var i int
fmt.Println("Enter an int:")
fmt.Scanln(&i)
fmt.Printf("You entered: %d\n", i)
readStdin.Close()
Вот результат программы:
Enter a string:
You entered: "mary had a little lamb"
Enter an int:
После приглашения «Enter an int:» программа ожидает неопределенное время и должна быть вручную остановлена. : (
Странно то, что если я изменю порядок событий (fmt.Scanln перед bufio.Scanner.Scan), то он работает отлично. Он также отлично работает, если я использую исключительно fmt.Scanln или исключительно используйте bufio.Scanner.Scan.
Все это заставляет меня думать:
a) Есть что-то уникальное в том, как Go обрабатывает ввод с клавиатуры
b) Там это какой-то другой тип разделителя, который я должен использовать при сканировании с помощью bufio.Scanner.Scan
c) Просто никогда не используйте эти два механизма сканирования вместе (пожалуйста, не позволяйте этому быть ответом!)