user3481276
user3481276

Reputation: 89

I encountered System.IndexOutOfRangeException when loading a txt file

I am trying the load a txt file which is written under a certain format, then I have encountered System.IndexOutOfRangeException. Do you have any idea on what's wrong with my codes? Thank you!

txt.File:

P§Thomas§40899§2§§§
P§Damian§40726§1§§§

P=Person; Thomas=first name; 40899=ID; 2=status

here are my codes:

using (StreamReader file = new StreamReader(fileName))
            {
                while (file.Peek() >= 0)
                {
                    string line = file.ReadLine();

                    char[] charSeparators = new char[] { '§' };
                    string[] parts = line.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);

                    foreach (PersonId personids in PersonIdDetails)
                    {
                        personids.ChildrenVisualisation.Clear();

                        foreach (PersonId personidchildren in personids.Children)
                        {
                            personidchildren.FirstName = parts[1];
                            personidchildren.ID = parts[2];
                            personidchildren.Status = parts[3];

                            personids.ChildrenVisualisation.Add(personidchildren);
                        }
                    }                             
                }
            }

at parts[1] the exception was thrown.

Upvotes: 0

Views: 1027

Answers (4)

user3383479
user3383479

Reputation:

Possible way to do it, It's just one solution between more solutions

    using (StreamReader file = new StreamReader(fileName))
        {
            while (file.Peek() >= 0)
            {
                string line = file.ReadLine();

                char[] charSeparators = new char[] { '§' };
                string[] parts = line.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);

                foreach (PersonId personids in PersonIdDetails)
                {
                    personids.ChildrenVisualisation.Clear();

                    foreach (PersonId personidchildren in personids.Children)
                    {
                       if(parts.Length > 3)//Only if you want to save lines with all parts but you can create an else clause for other lines with 1 or 2 parts depending on the length
                       {
                        personidchildren.FirstName = parts[1];
                        personidchildren.ID = parts[2];
                        personidchildren.Status = parts[3];

                        personids.ChildrenVisualisation.Add(personidchildren);
                       }
                    }
                }                             
            }
        }

Upvotes: 0

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

You should check if parts have enough items:

  ...

  string[] parts = line.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);

  foreach (PersonId personids in PersonIdDetails) {
    personids.ChildrenVisualisation.Clear();

    // Check if parts have enough infirmation: at least 3 items
    if (parts.Length > 3) // <- Pay attention for "> 3"
      foreach (PersonId personidchildren in personids.Children) {
        //TODO: Check, do you really start with 1, not with 0?
        personidchildren.FirstName = parts[1];
        personidchildren.ID = parts[2];
        personidchildren.Status = parts[3];

        personids.ChildrenVisualisation.Add(personidchildren);
      }
    else {
      // parts doesn't have enough data
      //TODO: clear personidchildren or throw an exception 
    } 
  }   

  ...

Upvotes: 1

flindeberg
flindeberg

Reputation: 5007

I'm given the impression that the actual file is not that big, so it might be useful to use File.ReadAllLines instead (the con is the you need to have the entire file in memory), which gives you all the lines.

Also, removing the lines which are either empty or just whitespace might be necessary.

        foreach (var line in File.ReadAllLines(fileName).Where(l => !string.IsNullOrWhiteSpace(l))
        {
           char[] charSeparators = new char[] { '§' };
           string[] parts = line.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);

           foreach (PersonId personids in PersonIdDetails)
           {
             personids.ChildrenVisualisation.Clear();

             foreach (PersonId personidchildren in personids.Children)
             {
               personidchildren.FirstName = parts[1];
               personidchildren.ID = parts[2];
               personidchildren.Status = parts[3];
               personids.ChildrenVisualisation.Add(personidchildren);
             }
           }
         }

Upvotes: 0

Mohamed
Mohamed

Reputation: 520

Change the first line to using (StreamReader file = new StreamReader(fileName, Encoding.GetEncoding("iso-8859-1")));

Upvotes: 0

Related Questions