Java循环内Scanner十六进制输入转十进制功能异常排查
十六进制转十进制代码错误排查与修复方案
现存代码问题汇总
- 循环索引越界:原倒序遍历循环起始值设为
hex.length()+1,Java字符串合法索引范围为0 ~ 字符串长度-1,首次调用charAt(i)就会触发字符串索引越界异常,导致程序直接跳出业务逻辑,这也是运行后仅输出That's all的核心原因。 - 大写字符判断范围错误:原逻辑判定大写十六进制字符范围为
'A'~'G',合法范围应为'A'~'F',字符'G'属于非法输入,原逻辑会错误将其识别为合法字符。 - 方法返回值错误:转换完成后返回的是记录幂次的
power变量,而非存储转换结果的dec变量,即使循环正常执行也会返回错误结果。 - 异常逻辑不符合需求:自定义了
HexToDecException但未实际使用,遇到非法字符时抛出的是IllegalArgumentException;且主方法直接打印异常栈轨迹,不符合非法输入输出Invalid hexadecimal number的要求。 - 异常捕获范围不合理:主方法将整个输入处理循环放在外层异常捕获块中,只要某一个输入触发异常,后续所有输入都会终止处理,无法完成全部测试用例的转换。
- 存在精度隐患:使用
Math.pow()做幂运算返回double类型,和整数直接运算存在浮点精度丢失风险,整数场景下用累乘计算更稳妥。
修复后完整可运行代码
import java.util.Scanner; class HexToDecException extends Exception { public HexToDecException(String msg) { super(msg); } } public class Main { public static int hexToDec(String hex) throws HexToDecException { int dec = 0; // 正序遍历通过累乘计算,无需单独维护幂次变量,避免索引错误和浮点精度问题 for (int i = 0; i < hex.length(); i++) { char currentChar = hex.charAt(i); int digit; if(currentChar>='0' && currentChar<='9'){ digit = currentChar - '0'; } else if(currentChar>='a' && currentChar<='f'){ digit = currentChar - 'a' + 10; } else if(currentChar>='A' && currentChar<='F'){ digit = currentChar - 'A' + 10; } else { throw new HexToDecException("Invalid hexadecimal number"); } dec = dec * 16 + digit; } return dec; } public static void main(String[] args){ Scanner scan = null; try{ scan = new Scanner(System.in); int n = scan.nextInt(); for(int i=0;i<n;i++) { String input = scan.next(); try { System.out.println(hexToDec(input)); } catch (HexToDecException e) { // 单个输入异常不影响后续处理 System.out.println(e.getMessage()); } } } catch(Exception ex){ ex.printStackTrace(); } finally{ if (scan != null) { scan.close(); } System.out.println("That's all."); } } }
修复后运行效果
针对测试用例输入5 6B 5 4AZ A5 9,实际输出与预期完全一致:
107 5 Invalid hexadecimal number 165 9 That's all.
内容的提问来源于stack exchange,提问作者user15273560
相关产品推荐
相关产品推荐

