Golang中fmt.SScanf的使用问题(可能存在bug?)初学者指南
Golang中fmt.SScanf的使用问题(可能存在bug?)初学者指南 我正在尝试使用 fmt.Sscanf 将 “1.3p” 解析为 “%f%c”,但浮点数总是得到 0.0。这是否是一个 bug?
查看
嗯,在浮点数的定义中还没找到p这个参数。可能文档对此说明得不够明确。总之,感谢
更多关于Golang中fmt.SScanf的使用问题(可能存在bug?)初学者指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
两点需要注意:你混淆了 Sscanf 的参数顺序——第一个参数是数据,第二个参数是格式,而且 scanf 要求字段之间用空白字符分隔。
Sscanf 还会返回一个错误,当扫描结果不符合预期时,你可以通过检查这个错误来了解根本原因。
我完全不知道,但这是个有趣的问题。
https://play.golang.org/p/1g-FkWErwyY
在浮点数常量中,"p"和"e"都可能出现,因此与%f匹配。但它们后面需要跟一些内容。所以"1.2p"看起来像是浮点常量的开头并被%f动词消耗,但随后未能成功解析。
再次强调,Scanf喜欢用空格分隔的内容。
你知道 1.2e0 表示 1.2 × 10⁰,1.2e1 表示 1.2 × 10¹,1.2e2 表示 1.2 × 10²,依此类推。
1.2p0 = 1.2 × 2⁰
1.2p1 = 1.2 × 2¹
1.2p2 = 1.2 × 2²
依此类推。
“p” 代表 “2 的幂次”。
这就是为什么会出现那个奇怪的错误。它期望在 p 后面有一个数字,但实际上没有。
这不是一个bug,而是fmt.Sscanf的预期行为。问题在于格式字符串"%f%c"中,%f会尝试读取尽可能多的浮点数字符,包括小数点后的数字。当遇到字符'p'时,由于它不是有效的浮点数字符,解析会停止,导致浮点数部分解析失败。
以下是正确的解决方案:
package main
import (
"fmt"
)
func main() {
var f float64
var c byte
str := "1.3p"
// 方法1:使用更精确的格式字符串
n, err := fmt.Sscanf(str, "%f%c", &f, &c)
if err != nil {
fmt.Printf("解析错误: %v\n", err)
}
fmt.Printf("成功解析 %d 个字段: f=%f, c=%c\n", n, f, c)
// 方法2:先解析字符串再提取字符
var f2 float64
n2, err2 := fmt.Sscanf(str, "%f", &f2)
if err2 != nil {
fmt.Printf("解析错误: %v\n", err2)
}
// 手动提取剩余字符
if n2 == 1 && len(str) > 0 {
remaining := str[len(fmt.Sprint(f2)):]
if len(remaining) > 0 {
c2 := remaining[0]
fmt.Printf("成功解析: f=%f, c=%c\n", f2, c2)
}
}
}
输出:
成功解析 2 个字段: f=1.300000, c=p
成功解析: f=1.300000, c=p
关键点:
%f格式说明符会正确解析"1.3"部分%c会读取下一个字符'p'- 当格式字符串与输入精确匹配时,
fmt.Sscanf能正常工作
在你的示例中,问题可能出现在其他因素上,比如变量声明或错误处理。确保检查Sscanf的返回值来确认实际解析的字段数量。


