2025年09月08日/ 浏览 6
在工业控制软件开发的实践中,用户输入校验往往是保证系统健壮性的第一道防线。最近在开发一个航空燃料表监控程序时,我遇到了一个典型的浮点数输入问题:当用户输入非数字字符或超出范围的数值时,程序要么崩溃,要么陷入死循环。本文将分享这个问题的完整解决过程。
原始代码的输入处理部分非常简单:
python
fuel_level = float(input("当前燃料量(0-10000升): "))
这种写法存在三个致命缺陷:
1. 输入字母或符号会触发ValueError
2. 负数或超大数据会被接受
3. 无法提供友好的重试机制
python
while True:
try:
fuel_level = float(input("当前燃料量(0-10000升): "))
break
except ValueError:
print("必须输入数字!")
这解决了崩溃问题,但依然接受-3.14或99999这样的无效值。
python
MINFUEL = 0
MAXFUEL = 10000
while True:
try:
fuellevel = float(input(f”当前燃料量({MINFUEL}-{MAXFUEL}升): “))
if MINFUEL <= fuellevel <= MAXFUEL:
break
print(f”数值必须在{MINFUEL}-{MAXFUEL}之间”)
except ValueError:
print(“必须输入有效数字!”)
当测试人员输入”12.3.45″时,发现仍然会异常。需要更严格的校验:
python
def validate_float(input_str):
try:
# 先验证是否能转换为float
value = float(input_str)
# 再验证字符串格式是否合法
if not re.match(r'^[0-9]+(\.[0-9]{1,2})?$', input_str):
raise ValueError
return value
except ValueError:
return None
结合以上经验,最终形成可复用的输入校验器:
python
import re
from typing import Optional
def getvalidatedfloat(
prompt: str,
minval: float = None,
maxval: float = None,
maxretries: int = 3
) -> Optional[float]:
“””获取经过验证的浮点数输入”””
retries = 0
while retries < maxretries:
user_input = input(prompt).strip()
# 基础格式校验
if not re.match(r'^-?\d+(\.\d+)?$', user_input):
print("错误:必须输入有效数字(如12.34)")
retries += 1
continue
try:
value = float(user_input)
# 范围校验
if (min_val is not None and value < min_val) or \
(max_val is not None and value > max_val):
print(f"错误:数值必须在{min_val}-{max_val}之间")
retries += 1
else:
return value
except ValueError:
retries += 1
print("无效输入,请重试")
print("超过最大重试次数")
return None
防御性编程原则:
用户体验优化:
性能考量:
这个案例告诉我们,看似简单的输入校验,实际上需要考虑数据类型、业务规则、用户体验等多个维度的因素。良好的输入处理机制应该像漏斗一样,层层过滤非法输入,同时为合法数据提供畅通无阻的通道。