简体   繁体   中英

Index outside of bounds of array when parsing file

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Net;
 using System.IO;
namespace App
{
 class Program
  {
    public static List<Types> List = new List<Types>();

    static void Main(string[] args)
    {                  
    using (StreamReader read = new StreamReader(fileName.xml))
           {
               read.ReadLine();
               while (!read.EndOfStream)
               {
                   string line = read.ReadLine();
                   string[] splitline = line.Split('|');
                   Types t = new Types();

                   t.nbr = Convert.ToInt64(splitline[0].Trim());
                   t.addr = splitline[1].Trim().Length > 1 ? splitline[3] : "";
                   List.Add(t);
               }
           }
        }
    }
  }

 public class Types
  {
    public Types()
    {
    }      
   public long nbr { get; set; } 
   public string addr { get; set; }
  }

I'm splitting the lines by '|' and after the split the text does not contain any of these '|' as well. Its specifically happening at this line

t.addr = splitline[1].Trim().Length > 1 ? splitline[3] : "";

I don't notice anything wrong with the text its parsing as I'm handle a null and such

Heres an example of what the text may look like:

 3612|
 1412|123 Circle st Miami,FL,87678
 1420|
 3587|23 Hamm st Chicago,IL,98678

You are trying to access the element of array that is not present that is why you are getting IndexOutOfRangeException exception. The exception is thrown when an attempt is made to access an element of an array with an index that is outside the bounds of the array

Check array length before you access its element and use Using try-catch block to safely handle the exception.

if(splitline > 0)
      t.nbr = Convert.ToInt64(splitline[0].Trim());  
if(splitline > 3)
      t.addr = splitline[1].Trim().Length > 1 ? splitline[3] : "";

And I don't see how you could get an index 3 using the sample text above.
After splitting the line, you have maximum two parts unless you split again the second substring using the comma as separator.

           ....       
           while (!read.EndOfStream)
           {
               string line = read.ReadLine();
               string[] splitline = line.Split('|', StringSplitOptions.RemoveEmptyEntries);
               Types t = new Types();
               Int64 num = 0;
               if(Int64.TryParse(splitline[0].Trim(), out num))
               {
                    t.nbr = num;
                    if(splitline.Length > 1)
                    {
                         // If you want the third substring of this second string
                         // i.e the 87678 from 1412|123 Circle st Miami,FL,87678
                         // string[] parts = splitline[1].Trim().Split(',');
                         // t.addr = (parts.Length > 2 ? parts[2] : "");

                         // If you want the whole string, no index 3
                         t.addr = splitline[1].Trim();

                    }
                    List.Add(t);
               }
           }

Also, for this kind of procedure is really good practice to always check if you have all the parts expected. Otherwise you run into nasty errors (Index out of Range).
Notice also the use of Int64.TryParse to avoid exceptions in case the first part of your line is not a number.

List<Types> list = new List<Types>();
String[] lines = File.ReadAllLines(filePath);

foreach (String line in lines)
{
    String[] split = line.Split(new Char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

    Types t = new Types();
    t.nbr = (split.Length > 0) ? Convert.ToInt64(split[0].Trim()) : 0;
    t.addr = (split.Length > 3) ? ((split[1].Trim().Length > 1) ? split[3] : String.Empty) : String.Empty;

    list.Add(t);
}

Sorry I completely overlooked something it was happening when the line looked like this: 1420|jskljal,dfkjdklj

so splitline[1] definitely had text in it and it was because the line says this: t.addr = splitline[1].Trim().Length > 1 ? splitline[3] <<< I was seeing if splitLine[1] has length then selecting a splitline[3] which doesn't exist.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM