Dart解析字符串为double报错:FormatException问题求助
Dart解析CSV字符串为Double时FormatException的解决方法
问题重现
使用Dart读取CSV文件,通过split()拆分行列后,尝试将字符串"1.5"用double.parse()转为double类型时抛出FormatException,即使调用trim()去除空白后仍报错,且确认CSV中数据格式为正确的十进制数。
相关代码:
map[columns[5]] = (map[columns[5]] ?? 0) + double.parse(columns[3]);
报错信息:
Reading from file: .\test.csv Unhandled exception: FormatException: Invalid double "1.5" #0 double.parse (dart:core-patch/double_patch.dart:112:28) #1 main (...) #2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:295:33) #3 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)
可能原因
表面上的"1.5"字符串可能包含不可见特殊字符(如零宽空格、全角小数点),或手动split()拆分CSV时逻辑错误,导致目标字符串并非预期的纯数值内容。
解决方案
1. 排查字符串真实内容
先打印目标字符串的字节编码,确认是否存在异常字符:
var targetStr = columns[3]; print('字符串内容: "$targetStr"'); print('字节编码: ${targetStr.codeUnits}');
正常"1.5"的字节编码应为[49, 46, 53],如果出现其他数值,说明存在特殊字符。
2. 清理特殊字符后解析
如果检测到非标准小数点(如全角点.)或其他干扰字符,先替换为标准格式再解析:
var cleanedStr = columns[3] .replaceAll(RegExp(r'[.,;]'), '.') // 替换常见非标准分隔符/小数点 .trim() .replaceAll(RegExp(r'\s'), ''); // 移除所有空白字符(包括不可见的) map[columns[5]] = (map[columns[5]] ?? 0) + double.parse(cleanedStr);
3. 使用健壮的解析方式
用double.tryParse()替代parse(),并在解析失败时输出详细信息,方便排查:
var targetStr = columns[3]; var parsedValue = double.tryParse(targetStr); if (parsedValue == null) { print('解析失败,字符串详情: 长度${targetStr.length}, 字节${targetStr.codeUnits}, 内容"$targetStr"'); } else { map[columns[5]] = (map[columns[5]] ?? 0) + parsedValue; }
4. 改用专业CSV解析库
手动split()无法处理CSV的复杂场景(如带引号的列、转义分隔符),推荐使用csv包来避免拆分错误:
- 在
pubspec.yaml添加依赖:
dependencies: csv: ^5.0.2
- 使用库解析CSV:
import 'dart:io'; import 'package:csv/csv.dart'; void main() async { var file = File('./test.csv'); var csvContent = await file.readAsString(); var rows = const CsvToListConverter().convert(csvContent); var map = <String, double>{}; for (var row in rows) { var valueStr = row[3] as String; var value = double.parse(valueStr); map[row[5] as String] = (map[row[5] as String] ?? 0) + value; } }
内容的提问来源于stack exchange,提问作者Anes Mezdoud
相关产品推荐
相关产品推荐

