
本文介绍如何使用 Go 语言逐行解析文本文件,提取类似国际象棋坐标的字母-数字对(如 A1、C3),并对字母是否超出 'A'–'H'、数字是否大于 8 进行严格校验,输出带行列位置的清晰错误提示。
本文介绍如何使用 go 语言逐行解析文本文件,提取类似国际象棋坐标的字母-数字对(如 `a1`、`c3`),并对字母是否超出 `'a'–'h'`、数字是否大于 `8` 进行严格校验,输出带行列位置的清晰错误提示。
在处理结构化文本输入(如棋盘坐标、坐标对列表)时,仅逐字符遍历是不够的——必须理解语义:每个有效单元由一个大写字母(A–H)后跟一个整数(1–8)组成,多个单元用英文逗号分隔(如 I9,A2)。原始代码中 if j > 'H' 的逻辑错误地将索引 j(整型下标)与字符 'H'(ASCII 值 72)比较,导致永远不触发;正确做法是取出对应位置的字节并判断其 ASCII 值,再结合后续数字字段做联合校验。
以下是完整、健壮的实现方案:
package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
// readLines 读取文件所有非空行,返回字符串切片
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() {
line := strings.TrimSpace(scanner.Text())
if line != "" { // 跳过空行
lines = append(lines, line)
}
}
return lines, scanner.Err()
}
// checkOne 校验单个坐标单元:字母范围 A-H,数字范围 1-8
func checkOne(letter byte, number, row, col int) {
if letter < 'A' || letter > 'H' {
fmt.Printf("invalid input letter %q @ (line %d, column %d)\n", letter, row, col)
}
if number < 1 || number > 8 {
fmt.Printf("invalid input number %d @ (line %d, column %d)\n", number, row, col+1)
}
}
func main() {
lines, err := readLines("chessin.txt")
if err != nil {
log.Fatalf("readLines: %v", err)
}
for i, line := range lines {
// 查找逗号分隔符,确保格式为 "XN,YN"
comma := strings.IndexByte(line, ',')
if comma == -1 {
log.Fatalf("missing comma in line %d: %q", i, line)
}
// 解析第一个坐标:letter + number(如 "I9" → 'I', 9)
if len(line) < 2 || comma < 1 {
log.Fatalf("malformed first coordinate in line %d: %q", i, line)
}
letter1 := line[0]
numStr1 := line[1:comma]
num1, err := strconv.Atoi(numStr1)
if err != nil {
log.Fatalf("invalid number '%s' in first coordinate, line %d: %v", numStr1, i, err)
}
checkOne(letter1, num1, i, 0)
// 解析第二个坐标:letter + number(如 "A2" → 'A', 2)
if len(line) <= comma+1 {
log.Fatalf("insufficient characters after comma in line %d: %q", i, line)
}
letter2 := line[comma+1]
numStr2 := line[comma+2:]
num2, err := strconv.Atoi(numStr2)
if err != nil {
log.Fatalf("invalid number '%s' in second coordinate, line %d: %v", numStr2, i, err)
}
checkOne(letter2, num2, i, comma+1)
}
}✅ 关键改进点说明:
- ✅ 语义化解析:不再盲目遍历每个字符,而是按 字母+数字,字母+数字 模式精准切分;
- ✅ 边界防护:检查逗号存在性、子串长度、空行及数字转换错误,避免 panic;
- ✅ 精准定位:错误信息包含 line 和 column 索引,便于调试与修复;
- ✅ 双向校验:不仅检查 > 'H',也覆盖 < 'A';不仅检查 > 8,也验证 ≥ 1(符合国际象棋实际坐标);
- ✅ 可扩展设计:checkOne 函数解耦校验逻辑,便于复用或增强(如支持小写、添加范围配置等)。
? 注意事项:
- 输入文件需为 UTF-8 编码,且坐标字母必须为大写 ASCII 字符(A–H);
- 数字部分不能含前导零(如 09 会被 strconv.Atoi 解析为 9,但若业务要求严格格式,应额外正则校验);
- 若需支持更复杂格式(如 A10 超出单格范围),应统一提升为“列名+行号”双维度模型,而非仅限 8×8 棋盘。
该方案兼顾健壮性、可读性与工程实践性,适用于配置校验、数据清洗及规则引擎前置检查等场景。

















