C#字符串转Double数组抛出FormatException异常如何解决
问题背景
在C#开发中实现输入字符串转Double类型数组功能时,编写代码如下:
class Program { public static void Main (string[] args) { string S1 = Console.ReadLine(); string S2 = Console.ReadLine(); double [] D1 = Array.ConvertAll(S1.Split(' '), Double.Parse); double [] D2 = Array.ConvertAll(S2.Split(' '), Double.Parse); } }
控制台输入内容后程序抛出异常,错误信息如下:
Unhandled exception. System.FormatException: Input string was not in a correct format.
at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type)
at System.Double.Parse(String s)
at System.Array.ConvertAll[TInput,TOutput](TInput[] array, Converter`2 converter)
at Program.Main(String[] args) in /home/runner/distancia-entre-dois-pontos/main.cs:line 9
异常产生原因
抛出System.FormatException的核心原因是Double.Parse方法接收到了无法被解析为合法双精度浮点数的字符串,结合运行路径判断,常见触发场景有三类:
- 区域文化不匹配:从运行路径中的项目名判断为葡萄牙语区域环境,
Double.Parse默认读取当前系统的区域文化规则解析数字,该区域下默认小数分隔符为逗号而非点号,若输入时使用点作为小数分隔符会直接触发格式错误,是该场景下最高发的诱因。 - 分割逻辑缺陷:直接使用
Split(' ')按单个空格分割输入字符串时,若输入存在连续空格、行首/行尾空格,会分割出空字符串,空字符串无法被解析为Double类型。 - 输入存在非法内容:若输入内容夹带字母、特殊符号等非数字字符,解析时也会抛出该异常。
修复方案
针对上述诱因,可通过三个调整解决问题:
- 优化分割逻辑:调用
Split方法时传入StringSplitOptions.RemoveEmptyEntries枚举参数,自动过滤分割产生的空字符串。 - 固定解析规则:指定使用不受系统区域设置影响的
CultureInfo.InvariantCulture作为解析文化规则,适配点号作为小数分隔符的通用输入格式。 - (可选)增加容错逻辑:使用
Double.TryParse替代直接调用Parse方法,遇到非法输入时可自定义处理逻辑,避免程序直接崩溃。
基础修复版本代码(适配点号分隔的小数输入,自动过滤空分割项):
using System; using System.Globalization; class Program { public static void Main (string[] args) { string S1 = Console.ReadLine(); string S2 = Console.ReadLine(); double [] D1 = Array.ConvertAll( S1.Split(' ', StringSplitOptions.RemoveEmptyEntries), s => Double.Parse(s, CultureInfo.InvariantCulture) ); double [] D2 = Array.ConvertAll( S2.Split(' ', StringSplitOptions.RemoveEmptyEntries), s => Double.Parse(s, CultureInfo.InvariantCulture) ); // 后续业务逻辑 } }
带容错的增强版本代码(遇到非法输入时提示后跳过,不会直接崩溃):
using System; using System.Globalization; using System.Collections.Generic; class Program { public static void Main (string[] args) { string S1 = Console.ReadLine(); string S2 = Console.ReadLine(); List<double> D1 = new List<double>(); foreach(string item in S1.Split(' ', StringSplitOptions.RemoveEmptyEntries)) { if(double.TryParse(item, NumberStyles.Float, CultureInfo.InvariantCulture, out double val)) { D1.Add(val); } else { Console.WriteLine($"输入项「{item}」不是合法数字,已自动跳过"); } } List<double> D2 = new List<double>(); foreach(string item in S2.Split(' ', StringSplitOptions.RemoveEmptyEntries)) { if(double.TryParse(item, NumberStyles.Float, CultureInfo.InvariantCulture, out double val)) { D2.Add(val); } else { Console.WriteLine($"输入项「{item}」不是合法数字,已自动跳过"); } } // 后续业务逻辑 } }
内容的提问来源于stack exchange,提问作者Arthur Oliveira
相关产品推荐
相关产品推荐

