
本文介绍如何使用 Go 语言逐行读取文本文件,按国际象棋坐标规则(字母 A–H、数字 1–8)校验每组坐标(如 A2,C3),对越界字母或数字输出带位置信息的错误提示。
本文介绍如何使用 go 语言逐行读取文本文件,按国际象棋坐标规则(字母 a–h、数字 1–8)校验每组坐标(如 `a2,c3`),对越界字母或数字输出带位置信息的错误提示。
在处理类似国际象棋坐标(如 A2,C3)的输入时,需严格遵循格式约束:列字母必须是 A–H(大写),行数字必须是 1–8。原始代码试图逐字符比较 j > 'H',但误将索引 j 当作字符值,导致逻辑错误;同时未正确提取和转换数字部分。以下是健壮、可维护的实现方案。
✅ 正确解析与校验流程
- 逐行读取:使用 bufio.Scanner 安全高效地读取所有非空行;
- 定位分隔符:用 strings.IndexByte(line, ',') 找到逗号位置,将一行拆为两个坐标(如 "I9" 和 "A2");
- 逐坐标解析:对每个坐标子串(如 "I9"),取首字节作为字母,剩余部分转为整数;
- 边界校验:字母 > 'H' 或数字 > 8 即视为非法,并输出精确行列位置(0-indexed);
- 错误处理:对解析失败(如非数字、缺失逗号)直接 panic,便于调试。
? 完整可运行代码
package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
func readLines(path string) ([]string, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
var lines []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
return lines, scanner.Err()
}
func checkOne(letter byte, number, row, col int) {
if letter 'H' {
fmt.Printf("invalid input %q @ (%d, %d)\n", letter, row, col)
}
if number 8 {
fmt.Printf("invalid input number %d @ (%d, %d)\n", number, row, col+1)
}
}
func main() {
lines, err := readLines("chessin.txt")
if err != nil {
log.Fatalf("readLines: %s", err)
}
for i, line := range lines {
// 查找逗号分隔符
comma := strings.IndexByte(line, ',')
if comma == -1 {
log.Fatalf("comma not found at line %d: %q", i, line)
}
// 解析第一个坐标:如 "I9" → letter='I', number=9
if len(line) <h3>⚠️ 关键注意事项</h3>
- 字符 vs 索引:line[j] 是字节(即字符),而 j 是索引——切勿混淆(原代码 if j > 'H' 是典型错误);
- 范围检查增强:checkOne 同时验证 letter 'H',避免无效字母(如小写 a 或符号)被忽略;
- 鲁棒性提升:添加了长度检查(len(line)
- 位置精度:列号 col 使用实际字节偏移(如 I9 中 'I' 在索引 0,'9' 在索引 1),便于定位问题源。
✅ 预期输出(对应 chessin.txt)
invalid input 'I' @ (0, 0) invalid input number 9 @ (0, 1) invalid input number 10 @ (1, 1) invalid input 'L' @ (2, 3)
该方案兼顾清晰性与工程实用性,适用于坐标校验、配置解析等需要精细字符级控制的场景。











