Search code examples
c#debuggingformatexception

Fixing a System.FormatException


I am writing a code that will look at a group in a text file called a, and if a line in that code contains the phrase "Savings Found" it will write out that line, and if has 30% or more savings it will place an asterisk in front and if it contains 30% or more and has $500 or more savings, it will place two asterisks. Below I have a sample data, an example of what the console needs to look like, and the code I have thus far:

    string find = "Savings found:";
    foreach (var line in a.Where(w => w.Contains(find)))
       {
          var subStr = line.Substring(line.IndexOf(find) + find.Length);
          var startIndex = subStr.IndexOf('(');
          var endIndex = subStr.IndexOf(')');

          var savings = double.Parse(subStr.Substring(0, startIndex - 1).Trim());
          var percent = double.Parse(subStr.Substring(startIndex + 1, endIndex - startIndex - 2).Trim());

          Console.WriteLine("{0}{1}{2}", (percent >= 30) ? "*" : string.Empty,

          (percent >= 30 && savings >= 500) ? "*" : string.Empty,
                                                        line);
         }

Sample data/example

* 5/21/2015 11:55:56 PM | Batch 6|386/767|50.33 %|CH2M-R|Processed NXRMN5...Checking refundable and non-refundable fares. Traditional Booking. Inside ticketing window. Minimum Savings Required: $131.00. Actual Savings: $257.18. Savings found: $257.18 (11.55 %). Savings were previously found.

The problem that I am having is I am getting a FormatException error, and I think I know what the problem is. The problem is that the value of subString is the 257.18 and everything after that. I don't want everything after it I just want the number. What can I do to get rid of that extra junk so it can compile?

This problem is similar to a previous question asked, however in that answer I get an ArgumentIndexOutOfBounds exception, tried to fix it, but did not go far in actually fixing the problem, hence the reasoning behind this question.


Solution

  • You can use regex for that:

    foreach(string line in a)
    {
        Match m = Regex.Match(line, @"Savings\s+found:\s*\$(?<savings>\d+\.\d+)\s*\(\s*(?<percent>\d+\.\d+)\s*%");
        if (m.Success)
        {
            decimal savings = decimal.Parse(m.Groups["savings"].Value, CultureInfo.InvariantCulture);
            decimal percent = decimal.Parse(m.Groups["percent"].Value, CultureInfo.InvariantCulture);
            string prefix = string.Empty;
            if (percent >= 30)
            {
                if (savings >= 500)
                    prefix = "**";
                else
                    prefix = "*";
            }
            Console.WriteLine(prefix + line);
        }
    }