double.Parse(123.342) System.FormatException: 'Input string was not in a correct format.'

Viewed 89

I am trying to read a file with lines that are looking like this one:

2 59816.6667 22966.6667

Why do I get this exception when I want to run this code:

string[] lines = File.ReadAllLines(path);

var points = new List<Point>();

foreach (var line in lines)
{
    var currentline = line.Split(' ');
    
    points.Add(new Point(
       double.Parse(currentline[1]), 
       double.Parse(currentline[2]), 
       double.Parse(currentline[0])
    ));
}

return points;

Point class:

class Point
{
    public Point(double x, double y, double iD)
    {
        X = x;
        Y = y;
        ID = iD;
    }

    public double X { get; set; }
    public double Y { get; set; }
    public double ID { get; set; }
}
2 Answers

Well, you have to debug. There are many posibilities (say, invisible unicode symbols). Let's have a Dump of the failed string:

    using System.Linq;

    ...

    private static string Dump(string value) {
      if (null == value)
        return "null";

      return "\"" + value + "\" " + 
             string.Join(" ", value.Select(c => ((int)c).ToString("x4")));
    } 

Then let's modify the loop a bit:

foreach (var line in lines)
{
    var currentline = line.Split(' ');

    double x, y, id;

    if (!double.TryParse(currentline[0], out id))
        throw new FormatException("{Dump(currentline[0])}  failed to be parsed as id");

    if (!double.TryParse(currentline[1], out x))
        throw new FormatException("{Dump(currentline[1])} failed to be parsed as X"); 

    if (!double.TryParse(currentline[2], out y))
        throw new FormatException("{Dump(currentline[2])} failed to be parsed as Y");

    points.Add(new Point(x, y, id));
}

Now you are going to have complete information of the string that's failed. Run the modified code once again over the file of interest, have the dump and see what's wrong with the string.

Could this possibly be because one of the lines does not contain the leading digit, and instead contains a leading space, in which case currentline[0] would be empty (and throw the said exception). You could try something like the following -

var currentline = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);

and also validate in each case that there are indeed 3 parts to the split (otherwise you will get an index out of range exception). Perhaps skip the loop in the first instance just to let it run through if currentline.Length < 3?

Related