C # - Unhandled exception of type System.FormatException - List String to List int

I get the error "FormatException was unhandled" - on this:

List<int> myStringList = LoadHours.ConvertAll(s => Int32.Parse(s)); 

I need to be able to do addition and division, so I'm trying to convert them to an integer. So I'm not sure how to handle this, do I need to convert them back to a string?

Code:

  //string txt = "Account: xxx123xxx\r\nAppID 10: 55 Hours 4 Minutes\r\n\r\nAccount: xxx124xxx\r\nAppID 730: 62 Hours 46 Minutes\r\nAppID 10: 3 Hours 11 Minutes\r\n\r\nAccount: xxx125xxx\r\nAppID 10: 0 Hours 31 Minutes\r\n"; string path = @"Hours.txt"; string text = File.ReadAllText(@"Hours.txt"); Regex pattern = new Regex(@"^((AppID (?<appid>\d+): ((?<hours>\d+) Hours )?((?<minutes>\d+) Minutes)?)|(Account: (?<account>xxx\d+xxx)))", RegexOptions.Multiline); string[] lines = File.ReadAllLines(path); int HrElapsed; int MinElapsed; Int32.TryParse(HoursElapsed(), out HrElapsed); Int32.TryParse(MinutesElapsed(), out MinElapsed); List < string > LoadHours = new List < string > (); List < string > LoadMinutes = new List < string > (); // Iterate through lines foreach(string line in lines) { //Check if line matches your format here Match match = pattern.Match(line); LoadHours.Add(match.Groups["hours"].Value); LoadMinutes.Add(match.Groups["minutes"].Value); //File.WriteAllText(@"Hours.txt", Regex.Replace(File.ReadAllText(@"Hours.txt"), @"AppID \d+:\s(\d+\s\w+\s\d+\s\w+)",LogTime)); } List < int > myStringList = LoadHours.ConvertAll(s => Int32.Parse(s)); List < int > myStringList2 = LoadMinutes.ConvertAll(s => Int32.Parse(s)); for (int i = 0; i < myStringList.Count; ++i) { myStringList[i] = myStringList[i] + HrElapsed; } for (int i = 0; i < myStringList2.Count; ++i) { myStringList2[i] = myStringList2[i] + MinElapsed; } string[] the_array = myStringList.Select(i => i.ToString()).ToArray(); string[] the_array2 = myStringList2.Select(i => i.ToString()).ToArray(); Regex re = new Regex(@"^((AppID (?<appid>\d+): ((?<hours>\d+) Hours )?((?<minutes>\d+) Minutes)?)|(Account: (?<account>xxx\d+xxx)))", RegexOptions.Multiline); string hackount = ""; (from m in re.Matches(text).Cast < Match > () let acc = m.Groups["account"].Value let app = m.Groups["appid"].Value // let hrs = m.Groups["hours"].Value // let mins = m.Groups["minutes"].Value let timHours = the_array let timMinutes = the_array2 let obj = new { Account = acc == "" ? hackount : (hackount = acc), AppId = app, Time = the_array, the_array2 } where app != "" select obj ).ToList().ForEach(Console.WriteLine); 

The Hours.txt file includes the following:

 Account: xxx123xxx AppID 10: 1 Hours 5 Minutes Account: xxx124xxx AppID 10: 2 Hours 6 Minutes AppID 10: 3 Hours 7 Minutes Account: xxx125xxx AppID 10: 4 Hours 8 Minutes 

I'm just trying to change the numbers of hours and minutes. Calculation of elapsed time (the amount of time that the program was open) and adding it to the amount already saved in the text file. Then save it back to the file, and do not output it to the console. (I parse the file and use regex to capture the numbers, and I think I need to do it if the protocol expression is> 60, similar to this afik):

  int TotalHours = HrElapsed + HrStored; int TotalMinutes = MinElapsed + MinStored; // Just making sure the minutes don't end up as "141 minutes" so it incrementing hours. if (TotalMinutes >= 60) { int remainder = TotalMinutes % 60; int whole = TotalMinutes / 60; TotalMinutes = remainder; TotalHours = TotalHours + whole; } 
+5
source share
2 answers

This is because you forgot to check whether your correspondence matches the regular expression.

 if (match.Success) // You need this check { LoadHours.Add(match.Groups["hours"].Value); LoadMinutes.Add(match.Groups["minutes"].Value); } 

In fact match.Groups["hours"].Value will simply return an empty string if the match fails. And then Int32.Parse(String.Empty) will throw a FormatException

A simple test:

  Regex pattern = new Regex(@"(?<hours>\d+)d"); Match match = pattern.Match("Textwithoutdigits"); var value = match.Groups["hours"].Value; Console.WriteLine(value == String.Empty); // <-- Will print true 
+2
source

As you can see, the problem is that you parse the invalid string as integers. You need to use the int.TryParse method.

You need to write your code as follows.

 List<int> myStringList = LoadHours.ConvertAll(s => TryParseString(s)); 

After that you need to create a method:

  private static int TryParseString(string p) { int result = 0; bool valid = int.TryParse(p, out result); if (!valid) return -1; return result; } 

Here you eliminate the invalid lines and put the value -1 for them. After that, if you want, you can remove this -1 value. A.

 myStringList = myStringList.Where(x=>x!=-1).ToList(); 
+1
source

Source: https://habr.com/ru/post/1237742/


All Articles