2

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; }
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • 1
    what's your locale? are you maybe in a region where the decimal separator is `,`? and have you evaluated if maybe in one of your lines there's invalid data? – Franz Gleichmann Mar 15 '21 at 09:55
  • Ok my decimal seperator in my region is "," –  Mar 15 '21 at 09:56
  • I tried to `for (int i = 0; i < currentline.Length; i++) { currentline[i].Replace(".", ","); } ` but this doesnt work –  Mar 15 '21 at 09:58
  • 1
    Does this answer your question? [Input string was not in a correct format #2](https://stackoverflow.com/questions/5275380/input-string-was-not-in-a-correct-format-2) – Self Mar 15 '21 at 09:58
  • Well your physical region is not relevant, but what `CultureInfo` is used by `double.Parse`. You don't provide one, so it uses `CultureInfo.CurrentCulture`. Which is it? And did you debug to verify the strings contain what you expected? – René Vogt Mar 15 '21 at 09:59
  • Or https://stackoverflow.com/questions/1354924/how-do-i-parse-a-string-with-a-decimal-point-to-a-double as target – Self Mar 15 '21 at 10:04
  • You may have blank lines. You can add : if(line.Length >0) – jdweng Mar 15 '21 at 10:07

2 Answers2

3

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.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
0

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?