# #go
Вопрос:
package main
import (
"fmt"
"log"
)
func main() {
var num int
n, err := fmt.Scanf("%d", amp;num)
fmt.Println(n, num)
if err != nil {
log.Fatalln(err)
}
var r1 rune
n, err = fmt.Scanf("%c", amp;r1)
fmt.Println(n, r1)
if err != nil {
log.Fatalln(err)
}
var r2 rune
n, err = fmt.Scanf("%c", amp;r2)
fmt.Println(n, r2)
if err != nil {
log.Fatalln(err)
}
}
ввод (клавиши клавиатуры):
1 enter a enter
вывод:
1 1
1 97
1 10
Почему значение r2
n
равно, но значение r1
равно a
?
В комментарии к fmt.Scanf
:
Новые строки во входных данных должны соответствовать новым строкам в формате. Единственное исключение: глагол %c всегда сканирует следующую руну во входных данных, даже если это пробел (или табуляция и т. Д.) Или новая строка.
Кажется, что новая строка после %d
съедается, а новая строка после %c
— нет. Соответствует ли новая строка после %d
пропуска?
Другой пример: https://play.studygolang.com/p/lRgxrUqyBTI , я пытаюсь использовать буфер для замены stdin, но результат отличается от использования stdin.
версия go go version go1.17.1 windows/amd64
Комментарии:
1. Однако вы не соответствуете новым строкам в формате, хотя вы процитировали документ, где вы сказали, что должны были.
2.
n, err = fmt.Scanf("%c", amp;r1)
. Я не знаю, почему%c
не соответствует новой строке после%d
, другими словами, перваяenter
съедается.3. ааа, понял. Спасибо. Ввод с терминала затрудняет воспроизведение подобных вопросов. Я не смог получить поведение, которое вы описываете для буферизованного ввода: play.golang.org/p/usHn6UhiKTU — Я понимаю
1 1 1 10 1 97
, чего мы и ожидали. Думаете, вы можете воспроизвести свою проблему на такой игровой площадке?4. Спасибо за ваш ответ. Результат получается
1 1 1 97 1 10
, когда я запускаю код в IDE GoLand и набираю1 enter a enter
напрямую, но результат1 1 1 10 1 97
(такой же, как у вас), когда я запускаю код сgo run main.go
помощью command и набираю1 enter a enter
текст.5. Я очень внимательно просмотрел документацию, и, честно говоря, я даже не вижу, где задокументировано, что новая строка заканчивается Scanf. Поэтому я думаю, что это хороший вопрос, поскольку рассматриваемая функция, по-видимому, недостаточно документирована. Если вы не получите хорошего ответа, напомните мне, и я щедро вознагражду это
Ответ №1:
новая строка — это один символ, который является допустимым вводом для руны, но не для int, поэтому при захвате руны новая строка считывается и сохраняется, в то время как для других типов это не делается.
если вы не захватите новую строку во время чтения в руну, вы получите сообщение об ошибке «неожиданное новое значение», если вы снова попытаетесь прочитать из стандартного ввода.
я предлагаю вам сделать следующее для чтения рун, чтобы вы всегда фиксировали новую строку и не получали неожиданных результатов
var r1, r2 rune
n, err = fmt.Scanf("%c%c", amp;r1, amp;r2)
fmt.Println(n, r1, r2)
if err != nil {
log.Fatalln(err)
}