C#读取CSV计算指定月份平均温度时匹配错误求助
问题修正方案
你的核心问题是用Contains做模糊匹配,会把日期中日部分包含输入数字的记录误判成目标月份。比如输入1时,2月1日(01/02/2024)的日期字符串里有1,就会被错误计入。下面给两种可靠的修正方式:
方法1:直接拆分日期字符串匹配月份
因为CSV里的日期格式是固定的DD/MM/YYYY,可以把日期按/拆分,直接取中间的月份部分做精确匹配:
using System; using System.IO; class Program { static void Main(string[] args) { string filepath = "temps.csv"; try { string[] lines = File.ReadAllLines(filepath); Console.WriteLine("From which month do you wish the avg is calculated? Jan (1) Feb (2)"); // 把用户输入转成整数,避免字符串匹配的前导零问题(比如文件里是"01",用户输入"1") if (!int.TryParse(Console.ReadLine(), out int targetMonth)) { Console.WriteLine("请输入有效的月份数字(1-12)"); return; } double sum = 0; int countDay = 0; // 跳过表头(如果CSV第一行是date;min;avg;max的话) for (int i = 1; i < lines.Length; i++) { string line = lines[i]; string[] parts = line.Split(';'); // 确保日期部分格式正确 if (parts.Length < 1) continue; string[] dateParts = parts[0].Split('/'); if (dateParts.Length != 3) continue; // 解析月份并和目标月份比较 if (int.TryParse(dateParts[1], out int currentMonth) && currentMonth == targetMonth) { // 确保平均温度能正确解析 if (double.TryParse(parts[2], out double avgTemp)) { sum += avgTemp; countDay++; } } } if (countDay == 0) { Console.WriteLine("未找到该月份的有效数据"); return; } double average = sum / countDay; Console.WriteLine($"The avg temp of month {targetMonth} is: {average:F2}"); } catch (IOException e) { Console.WriteLine("Error reading file: " + e.Message); } } }
方法2:用DateTime解析日期(更健壮)
直接把日期字符串转成DateTime对象,通过Month属性精确匹配,还能自动验证日期的合法性:
using System; using System.IO; class Program { static void Main(string[] args) { string filepath = "temps.csv"; // 定义日期格式,和CSV里的DD/MM/YYYY对应 string dateFormat = "dd/MM/yyyy"; try { string[] lines = File.ReadAllLines(filepath); Console.WriteLine("From which month do you wish the avg is calculated? Jan (1) Feb (2)"); if (!int.TryParse(Console.ReadLine(), out int targetMonth) || targetMonth < 1 || targetMonth > 12) { Console.WriteLine("请输入1-12之间的有效月份数字"); return; } double sum = 0; int countDay = 0; // 跳过表头行 for (int i = 1; i < lines.Length; i++) { string line = lines[i]; string[] parts = line.Split(';'); if (parts.Length < 3) continue; // 解析日期,格式严格匹配DD/MM/YYYY if (DateTime.TryParseExact(parts[0], dateFormat, null, System.Globalization.DateTimeStyles.None, out DateTime date)) { if (date.Month == targetMonth) { if (double.TryParse(parts[2], out double avgTemp)) { sum += avgTemp; countDay++; } } } else { Console.WriteLine($"无效日期格式:{parts[0]},已跳过该行"); } } if (countDay == 0) { Console.WriteLine("未找到该月份的有效数据"); return; } double average = sum / countDay; Console.WriteLine($"The avg temp of month {targetMonth} is: {average:F2}"); } catch (IOException e) { Console.WriteLine("Error reading file: " + e.Message); } } }
关键修改点说明
- 替换
Contains为精确匹配:要么拆分日期取月份部分转整数比较,要么用DateTime解析后取Month属性 - 增加输入验证:确保用户输入的是1-12的有效数字
- 增加数据合法性校验:解析日期和温度时用
TryParse/TryParseExact,避免格式错误导致崩溃 - 跳过表头行:如果CSV第一行是字段名(date;min;avg;max),直接跳过避免解析错误
- 处理无数据情况:当countDay为0时给出提示,避免除以零错误
内容的提问来源于stack exchange,提问作者Vitor Rocha
相关产品推荐
相关产品推荐

