Reputation: 3
I'm currently in the middle of trying to take a '|' delimited text file and create objects from the data contained within. Example:
Name|Address|City|State|Zip|Birthday|ID|Etc.
Name2|Address2|City2|State2|Zip2|Birthday2|ID2|Etc.
The newly created object, is then added to a list of said objects and the program moves to the next line of the file by way of a while loop using .Peek() (to make sure I don't go past the end of the file).
However, when it gets to creating the second object (more specifically, the second field of the second object), it throws an Index Out Of Range Exception, and I can't for the life of me figure out why. Thank you whomever might read this!
StreamReader textIn = new StreamReader(new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read));
List<Student> students = new List<Student>();
while (textIn.Peek() != -1)
{
string row = textIn.ReadLine();
MessageBox.Show(row);
string [] fields = row.Split('|');
Student temp = new Student();
try
{
temp.name = fields[0];
temp.address = fields[1];
temp.city = fields[2];
temp.state = fields[3];
temp.zipCode = Convert.ToInt32(fields[4]);
temp.birthdate = fields[5];
temp.studentID = Convert.ToInt32(fields[6]);
temp.sGPA = Convert.ToDouble(fields[7]);
}
catch
{
MessageBox.Show("IndexOutOfRangeException caught");
}
students.Add(temp);
}
textIn.Close();
Upvotes: 0
Views: 1447
Reputation: 148120
In the given data if you have atleast eight columns for every row, you wont be getting index of of range exception but parsing of item at 4, 6, 7 would fail
as they are not
numbers and converting the non number values to int and double raises the exception.
temp.zipCode = Convert.ToInt32(fields[4]);
temp.studentID = Convert.ToInt32(fields[6]);
temp.sGPA = Convert.ToDouble(fields[7]);
You need to change the catch block to know the reason for exception
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
Upvotes: 0
Reputation: 43596
Maybe ReadAllLines
will work a bit better if the data is on each line:
List<Student> students = new List<Student>();
using (FileStream textIn = new FileStream(path, FileMode.Open, FileAccess.Read))
{
foreach (string line in File.ReadAllLines(path))
{
MessageBox.Show(line);
string[] fields = line.Split('|');
Student temp = new Student();
try
{
temp.name = fields[0];
temp.address = fields[1];
temp.city = fields[2];
temp.state = fields[3];
temp.zipCode = Convert.ToInt32(fields[4]);
temp.birthdate = fields[5];
temp.studentID = Convert.ToInt32(fields[6]);
temp.sGPA = Convert.ToDouble(fields[7]);
}
catch
{
MessageBox.Show(string.Format("IndexOutOfRangeException caught, Split Result:", string.Join(", ", fields.ToArray())));
}
students.Add(temp);
}
}
Upvotes: 0
Reputation: 18534
while (!textIn.EndOfStream)
instead. try
{
int tempInt;
double tempDouble;
if (fields.Length = 8)//#1
{
temp.name = fields[0];
temp.address = fields[1];
temp.city = fields[2];
temp.state = fields[3];
if (!int.TryParse(fields[4], out tempInt)) //#4
temp.zipCode = tempInt;
else
{
//..invalid value in field
}
temp.birthdate = fields[5];
if (!int.TryParse(fields[6], out tempInt)) //#4
temp.studentID = tempInt;
else
{
//..invalid value in field
}
if (!int.TryParse(fields[7], out tempDouble)) //#4
temp.sGPA = tempDouble;
else
{
//..invalid value in field
}
}
else //#2
{
MessageBox.Show("Invalid number of fields");
}
}
catch (Exception ex) //#3
{
MessageBox.Show(ex.Message);
}
Upvotes: 0
Reputation: 223257
First you can't ensure if its a IndexOutOfRange Exception with your current catch block.
catch
{
MessageBox.Show("IndexOutOfRangeException caught");
}
It can be anything, may be exception during parsing to double. You may modify your catch block to:
catch(IndexOutOfRangeException ex)
{
MessageBox.Show(ex.Message);
}
Also if you are going to access fields[7]
then its better if you can check against the length of array to ensure that you got atleast 8 elements in your array.
if(fileds.Length >=8)
{
temp.name = fields[0];
....
To catch FormatException
which can occur during double parsing you may add an extra catch block for:
catch (FormatException ex)
{
MessageBox.Show(ex.Message);
}
Upvotes: 1