使用Golang制作一个BMI指数计算器 Go语言控制台输入输出处理

1次阅读

使用Golang制作一个BMI指数计算器 Go语言控制台输入输出处理

go 里怎么用 fmt.Scan 安全读取浮点数

直接用 fmt.Scan 读身高体重,很容易卡住或 panic——比如用户输了个字母,fmt.Scan 会失败且不清除输入缓冲区,下次再读就立刻返回错误。更糟的是,它对空格、换行不敏感,但对类型错配零容忍。

  • 永远用 fmt.Scanln 替代 fmt.Scan:它只读一行,遇换行即停,避免残留输入干扰后续读取
  • 必须检查返回值:fmt.Scanln 返回 (n int, err Error)n != 2err != nil 都要处理
  • 别用 float64 直接接收:先读 String,再用 strconv.ParseFloat 转,并设精度(如 64),否则可能因 locale 导致解析失败

计算 BMI 时单位和精度怎么拿捏

BMI 公式是 weight(kg) / height(m)²,但用户大概率输的是厘米和公斤。如果让用户自己换算,体验差;让程序硬转,又容易出错。

  • 默认按「厘米 + 公斤」接受输入,内部统一转成米:高度除以 100.0,不是 100(避免整数除法)
  • 结果保留一位小数就够了:math.Round(bmi*10) / 10,别用 fmt.printf("%.1f") 做判断依据——那是格式化输出,不是数值截断
  • 注意边界:身高 0 或负数、体重 ≤ 0 必须拒绝,否则除零或无意义

怎么把 BMI 值映射成中文分类(避免 if 砌)

WHO 和中国标准略有不同,硬写一串 if else 不仅难维护,还容易漏掉边界(比如 和 <code> 差一个临界点)。

  • 用结构体数组预定义区间:[]struct{ low, high float64; label string },按 low 升序排,遍历匹配
  • 每个区间用左闭右开(low ),最后一项 <code>high 设为 math.Inf(1),覆盖超重/肥胖上限
  • 别在循环里重复计算:提前验证 bmi 是否为有效数字(!math.IsNaN(bmi) && !math.IsInf(bmi, 0)

为什么 os.Stdin 需要手动清理错误后的输入流

fmt.Scanln 因输入非数字失败时,非法字符仍留在 os.Stdin 缓冲区。下一次读取会立刻撞上它,形成死循环。

立即学习go语言免费学习笔记(深入)”;

  • 检测到 err != nil 后,必须调用 bufio.NewReader(os.Stdin).ReadBytes('n') 清掉整行残渣
  • 不要用 fmt.Scanln(&dummy) 消耗——如果只剩换行符,它会阻塞等待新输入
  • 整个流程建议包在 for 循环里,每次成功才 break,失败就提示重输并清缓冲

最麻烦的不是算 BMI,是让程序在用户乱输、中途 Ctrl+C、输一半回车这些真实场景下不崩、不卡、不静默退出。输入校验和缓冲区管理,比公式本身花的时间多三倍。

text=ZqhQzanResources