Golang实现HackerRank Day8挑战:为何bufio.NewReader少输出一行?
bufio.NewReader与bufio.NewScanner在HackerRank上的输出差异原因
我在本地终端用bufio.NewReader实现HackerRank Day8通讯录查询挑战时输出正常,但在HackerRank平台上会少输出一行结果,切换为bufio.NewScanner后问题解决。
出错的代码
func main() { reader := bufio.NewReader(os.Stdin) // 读取条目数量 line, _ := reader.ReadString('\n') num, _ := strconv.Atoi(strings.TrimSpace(line)) // 创建通讯录Map phonebook := make(map[string]string) // 读取num行姓名和电话 for i := 0; i < num; i++ { line, _ = reader.ReadString('\n') parts := strings.Fields(line) name := parts[0] number := parts[1] phonebook[name] = number } var results []string // 处理查询直到EOF for i := 0; i < num; i++ { qu, err := reader.ReadString('\n') if err != nil { break } qu = strings.TrimSpace(qu) if phone, found := phonebook[qu]; found { results = append(results, fmt.Sprintf("%s=%s", qu, phone)) } else { results = append(results, "Not found") } } }
正常运行的代码
func main() { scanner := bufio.NewScanner(os.Stdin) // 读取条目数量 scanner.Scan() num, _ := strconv.Atoi(strings.TrimSpace(scanner.Text())) // 创建通讯录Map phonebook := make(map[string]string) // 读取num行姓名和电话 for i := 0; i < num; i++ { scanner.Scan() parts := strings.Fields(scanner.Text()) name := parts[0] number := parts[1] phonebook[name] = number } var results []string // 处理剩余所有输入作为查询 for scanner.Scan() { qu := strings.TrimSpace(scanner.Text()) if phone, found := phonebook[qu]; found { results = append(results, fmt.Sprintf("%s=%s", qu, phone)) } else { results = append(results, "Not found") } } // 检查扫描错误 if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "读取输入错误:", err) } // 一次性输出所有结果 fmt.Println(strings.Join(results, "\n")) }
示例输入输出
示例输入
3 sam 99912222 tom 11122222 harry 12299933 sam edward harry
(注:平台输入也可能存在无换行的情况,比如所有内容在同一行)
预期输出
sam=99912222 Not found harry=12299933
使用bufio.NewReader的输出
sam=99912222 Not found
使用bufio.NewScanner的输出
sam=99912222 Not found harry=12299933
差异原因分析
查询循环逻辑错误
出错代码中处理查询的循环是for i := 0; i < num; i++,错误地假设查询数量等于通讯录条目数量num。但题目要求是处理所有后续输入直到EOF,而非固定num次查询,这个逻辑本身就不符合题目要求。EOF处理方式不同
bufio.NewReader.ReadString('\n')依赖换行符分割内容:如果输入的最后一行没有换行符,它会返回该行内容并附带io.EOF错误,出错代码遇到错误直接break循环,导致最后一个查询被丢弃。bufio.NewScanner.Scan()会自动适配无换行的结尾:只要还有未读取的内容,即使没有换行符,Scan()也会返回true并读取内容,直到真正的EOF才停止,不会遗漏最后一条查询。
输入格式兼容性问题
HackerRank平台的输入可能存在不规范的换行(比如所有内容在同一行),bufio.NewScanner默认的扫描行为(按行分割,同时处理空白字符)比ReadString('\n')更健壮,能适应不同的输入格式;而ReadString('\n')依赖明确的换行符,一旦输入未按预期换行就会读取错误内容,导致后续逻辑异常。
内容的提问来源于stack exchange,提问作者Dia
相关产品推荐
相关产品推荐

