

新闻资讯
技术学院go 的 `fmt.sscanf` 不支持“必须恰好匹配指定字符数”的语义,但可通过 `strconv.parseuint` 结合长度预检实现严格两位十六进制解析。
在 Go 中,fmt.Sscanf 的格式化行为是“最多匹配”,而非“恰好匹配”。例如 %02x 仅表示“以至少两位、不足则补零的方式解析十六进制”,但输入 "f!" 仍会成功解析 'f'(即 0xf = 15),忽略后续非法字符 !,且 n 返回 1(成功读取 1 个值),无法区分 "f"、"ff" 或 "f!" —— 这显然不符合“必须严格两位合法十六进制字符”的业务需求(如解析 MAC 地址字节、固定宽编码等)。
此时应放弃 fmt.Sscanf,改用 strconv.ParseUint 配合显式长度校验。核心逻辑分三步:
以下为生产就绪的示例代码:
package main
import (
"fmt"
"strconv"
)
// ParseHexByte parses exactly size hex digits (e.g., "ff") into uint8.
// Returns error if length ≠ size or contains invalid hex chars.
func ParseHexByte(s string, size int) (uint8, error) {
if len(s) != size {
return 0, strconv.ErrSyntax // explicit length mismatch
}
n, err := strconv.ParseUint(s, 16, 8)
return uint8(n), err
}
func main() {
testCases := []string{"ff", "f", "", "f!", "12", "00", "fff"}
for _, s := range testCases {
if v, err :=
ParseHexByte(s, 2); err == nil {
fmt.Printf("✓ %q → %d\n", s, v)
} else {
fmt.Printf("✗ %q → %v\n", s, err)
}
}
}输出结果:
✓ "ff" → 255 ✗ "f" → strconv.ParseUint: parsing "f": invalid syntax ✗ "" → strconv.ParseUint: parsing "": invalid syntax ✗ "f!" → strconv.ParseUint: parsing "f!": invalid syntax ✓ "12" → 18 ✓ "00" → 0 ✗ "fff" → strconv.ParseUint: parsing "fff": invalid syntax
✅ 关键优势:
⚠️ 注意事项:
综上,当需要“精确字符数 + 严格语法”双重校验时,strconv.ParseUint + 显式长度检查是 Go 中最直接、可靠且符合惯用法的解决方案。