Reputation: 31
I got stuck writing some simple program which writes some data to the text file and reads them form this file later.
I have a function that writes lines to a txt file; each line contains Name, Surname, and Idnumber.
And below I have a function that reads the data from that file.
I want to separate Name, Surname and Idnumber so below code seems to be correct but during debugging I got a message "An unhandled exception of type 'System.NullReferenceException' occurred" for this line:
string[] tabstring = myString.Split(' ', ' ');
.
I created the tab string which contains 3 elements - each for each word in the line i.e. tabstring[0]=Name and so on.
The while
loop is to do it for each line in the text file. But something is wrong.
public void ReadFromFile()
{
FileStream fsListOfObjects = new FileStream("C:\\Users\\Dom\\Desktop\\ListOfObjects.txt",
FileMode.Open);
StreamReader srListOfObjects = new StreamReader(fsListOfObjects);
while (srListOfObjects.ReadLine() != null)
{
string myString= (srListOfObjects.ReadLine();
Console.WriteLine(myString);
**string[] tabstring = myString.Split(' ', ' ');**
Name = tabstring[0];
Surname = tabstring[1];
Id= long.Parse(tabstring[2]);
ClassName object= new ClassName(Name, Surname, Id);
myList.Add(object);
}
srListOfObjects.Close();
Console.ReadLine();
}
And here is what the text file looks like:
Ann Brown 1233456789
Bruce Willis 098987875
Bill Gates 789678678
and so on...
I would appreciate your comments on the described problem.
Upvotes: 1
Views: 1832
Reputation: 25023
while (srListOfObjects.ReadLine()..
reads a line but doesn't save it into a variable. string myString= (srListOfObjects.ReadLine())
reads another line.
Use while (!srListOfObjects.EndOfStream)
to check for the end of the stream: StreamReader.EndOfStream Property.
Also, it is a good idea to check that the correct number of parts of the string were obtained by the Split - it guards against things like lines with only whitespace.
Things like StreamReaders need have .Dispose() called on them to clear up "unmanaged resources" - an easy way to do that which will work even if the program crashes is to use the using
statement.
If you make the ReadFromFile
method into a function instead of a void then you can avoid (no pun) using a global variable for the data. Global variables are not necessarily a problem, but it's usually good to avoid them.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace ConsoleApp1
{
public class ClassName
{
public string Name { get; set; }
public string Surname { get; set; }
public long Id { get; set; }
}
class Program
{
public static List<ClassName> ReadFromFile(string fileName)
{
var result = new List<ClassName>();
using (var sr = new StreamReader(fileName))
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
var parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Count() == 3)
{
result.Add(new ClassName
{
Name = parts[0],
Surname = parts[1],
Id = long.Parse(parts[2])
});
}
}
}
return result;
}
static void Main(string[] args)
{
string myFile = @"C:\temp\namesList.txt";
var theList = ReadFromFile(myFile);
foreach(var c in theList)
{
Console.WriteLine($"{c.Id} - {c.Surname}, {c.Name}");
}
Console.ReadLine();
}
}
}
outputs:
1233456789 - Brown, Ann
98987875 - Willis, Bruce
789678678 - Gates, Bill
Upvotes: 2
Reputation: 32760
Your problem is here:
while (srListOfObjects.ReadLine() != null)
{
string myString= (srListOfObjects.ReadLine();
You are entering the loop on the condition that srListOfObjects.ReadLine()
returns something other than null
but then you are immediately reading a new line form srListOfObjects
and storing the returned reference in myString
. This has obviously two problems:
ReadLine
can return null
and you are not checking if it is. The error you are getting is due to this reason.Update:
You should only read one line per iteration. One way to do it is declaring and initializing myString
before entering the loop and updating it on every iteration:
var myString = srListOfObjects.ReadLine();
while (myString != null)
{
//do your stuff
myString = srListOfObjects.ReadLine();
}
Upvotes: 0
Reputation: 7585
https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readline?view=netcore-3.1
ReadLine() - Reads a line of characters from the current stream and returns the data as a string.
In your code you do a null check, but then call ReadLine again. When you hit the last line, you will get a NULL string, and splitting that will fail with the NULL ref
Upvotes: 0