1

So I have this code that supposedly works when I check if the array "vetorUtilizadores" is created, but it somehow makes my string "linha" null, which gives me a error: "object reference not set as an object". Here's a screenshot: https://imgur.com/a/9LK2p (that's test data, of course)

string linha = "";
string login = @"utilizadores.txt";
StreamReader sr = File.OpenText(login);
while(linha != null)
{
    linha = sr.ReadLine();
    string[] vetorUtilizadores = linha.Split(';');
}

(Sorry if I did something wrong on this post btw, kinda new to these type of forums.)

Erik Philips
  • 48,663
  • 7
  • 112
  • 142
Manuel
  • 43
  • 10
  • do you have anything in the text file utilizadores.txt? – Joseph Mawer Jan 05 '18 at 18:00
  • 6
    `StreamReader.ReadLine` returns `null` if you've reached the end of the file. –  Jan 05 '18 at 18:00
  • 1
    Try shortening it to while((linha = sr.ReadLine()) != null) – Valuator Jan 05 '18 at 18:01
  • You need to check for `null` after you call `sr.ReadLine()` because if you are at the end of the file it will return `null` – pstrjds Jan 05 '18 at 18:01
  • Which means that splitting linha will result in an exception, before the while loop checks for nullity. – Ric Gaudet Jan 05 '18 at 18:01
  • 3
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) –  Jan 05 '18 at 18:01
  • Not related to your question, but don't forget to close the stream in the end `sr.Close()`. – z m Jan 05 '18 at 18:15

6 Answers6

6

The last time through the loop, the code first checks for null, but finds a value. It then reads from the file and returns null into the linha variable. Next it tries to split the null string, which causes your error. Finally (assuming you catch the exception) it will go back to the beginning of the loop and check for null again. This time it will find null and quit the loop.

To fix this, you need to read from the file before you check for null. You can use this pattern:

string login = @"utilizadores.txt";
using (StreamReader sr = File.OpenText(login))
{
    string linha = sr.ReadLine();
    while(linha != null)
    {
        string[] vetorUtilizadores = linha.Split(';');
        linha = sr.ReadLine();
    }
}

or this pattern:

string linha = "";
string login = @"utilizadores.txt";
using (StreamReader sr = File.OpenText(login))
{
    while((linha = sr.ReadLine()) != null)
    {
        string[] vetorUtilizadores = linha.Split(';');
    }
}

Note the addition of using blocks around the StreamReader. That really is important.

You can also use this pattern:

string login = @"utilizadores.txt";
var lines = File.ReadLines(login).Select(linha => linha.Split(';'));

That last one might eventually let you write code like this:

bool validAccount = lines.Any(x => x[0] == username && x[1] == password);

What's really nice here is if your user is the first person in the list, that code only ever reads the first line from the file. Of course, if they are not in the list at all it will still need to read through the entire file, but at least you have a chance to save on some disk I/O.

And of course I'm assuming this is student code. No one really keeps a username/password list in a plain text file. Right?

Joel Coehoorn
  • 362,140
  • 107
  • 528
  • 764
4

You are checking the line value for null and then modifing it. At the end of the file it will be null and you'll get the error. Change your code to this:

string linha = "";
string login = @"utilizadores.txt";
StreamReader sr = File.OpenText(login);
while((linha=sr.ReadLine()) != null)
{
   string[] vetorUtilizadores = linha.Split(';');
}
Magnetron
  • 4,985
  • 1
  • 16
  • 32
1

This is happening because the code reads line after checking for null. Try this:

while((linha = sr.ReadLine()) != null)
{
    string[] vetorUtilizadores = linha.Split(';');
}

Now the line is read and checked for null in the loop condition, so the loop will stop as soon as ReadLine returns null.

izr
  • 66
  • 2
0

The line

linha = sr.ReadLine();

will set linha to null once the end of the stream is reached. You properly check that in your while loop while(linha != null), but before that line runs, you run the line

string[] vetorUtilizadores = linha.Split(';');

which will throw a null reference exception when linha is null.

ILMTitan
  • 10,147
  • 2
  • 26
  • 43
0

I suggest you check the end of stream istead of linha != null:

while(!sr.EndOfStream)
{
    linha = sr.ReadLine();
    if(!string.IsNullOrWhiteSpace(linha))
    {
        string[] vetorUtilizadores = linha.Split(';');
    }
}
Diego Rafael Souza
  • 4,599
  • 3
  • 18
  • 52
-5

If the text file is empty the linha = sr.ReadLine() will set your variable to null. Make sure you have some text in your file.

Joseph Mawer
  • 240
  • 4
  • 13