-1

I keep getting the error in title. I am not very experienced in coding and am not great at reading code and understanding it yet.

I also know this will be a simple fix but still I don't know what or where I need to fix.

using System;
using System.Linq;

namespace Day_6
{
    class Program
    {
        static void Main(string[] args)
        {
            int numStrings = Convert.ToInt32(Console.ReadLine());
            var str = "";
            string[] words = new string[1000];

            var even = new string[500];
            var odd = new string[500];

            for (int i = 0; i < numStrings; i++)
            {
                str = Console.ReadLine();
                words.Append(str);
            }

            foreach (var word in words)
            {
                foreach (var letter in word)
                {
                    if (word.IndexOf(letter)%2 != 0)
                    {
                        odd.Append(letter.ToString());
                    }
                    else
                    {
                        even.Append(letter.ToString());
                    }
                }
                Console.WriteLine(odd + " " + even);
            }
        }
    }
}

Any help, even if it is just material to read so I can understand why/what/where I am getting this error would be great.

After all I am trying to learn!

Many thanks

  • 3
    Does this answer your question? [What does "Object reference not set to an instance of an object" mean?](https://stackoverflow.com/questions/779091/what-does-object-reference-not-set-to-an-instance-of-an-object-mean) – Mocha Jul 24 '20 at 00:12
  • Who told you to use arrays? As a beginner, you should not be using arrays. If you're getting this idea from a tutorial, find a better tutorial. You should be using List and you should never specify a size in the constructor. That is just not how C# does things. – JoelFan Jul 24 '20 at 00:21
  • So I understand that "word" in the foreach loops is = to null. But I am not sure why the word is not set to the strings added into the array earlier in the code – frosty1777 Jul 24 '20 at 00:25
  • 1
    Do you know how to debug? Set a breakpoint on entry then press f11 to single step to see the error. – JWP Jul 24 '20 at 00:27
  • JoelFan, thanks I will use Lists. could you explain why lists over arrays and also why specifying size in the constructor is bad? Thanks – frosty1777 Jul 24 '20 at 00:28
  • John Peters, Yes - I have set breakpoints and tried to debug. But all I understood was that "word" was set to null (instead of what should have been in the array) but not why that was happening – frosty1777 Jul 24 '20 at 00:29

2 Answers2

0

The first instance of null-reference error is caused by line 17 where you have words.Append(str);, replace it with words[i] = str;.

Read about the behaviour of IEnumerable.Append() method here, because it does not modify the array words in place; it returns a new IEnumerable, which must then be enumerated to an array.

So the statement words.Append(str); actually does nothing; if you wish to use the Append() method, you must save it's return value and enumerate the result to an array like so:

words = words.Append(str).ToArray()

Also, there's a second null-reference error in the 3rd statement in your Main() method (line 9), where you have

string[] words = new string[1000];

If you replace it with:

string[] words = new string[numStrings];

You will remove the possibility of your foreach loop looping over null elements.

mamift
  • 300
  • 4
  • 10
0

If you have to use Arrays like you are doing, change your assignment for loop to the following,

for (int i = 0; i < numStrings; i++)
{
    str = Console.ReadLine();
    words[i] = str; // Assign to elements of Array (not Append).
}

and then you want to iterate over words that are not null (initial array is all nulls). You will need to use index for each of the even and odd arrays as well. You cannot use indexOf either to check if your character is even or odd... if you do that, then any duplicate letter will not work. Use an iteration index for that as well.

int evenIndex = 0;
int oddIndex = 0;
int iterationIndex = 0;
foreach (var word in words.Where(x => x != null))
{
    foreach (var letter in word)
    {
        if (iterationIndex++ % 2 != 0)
        {
            odd[oddIndex++] = (letter.ToString());
        }
        else
        {
            even[evenIndex++] = (letter.ToString());
        }
    }
}
// Print this "outside" of your for loops
Console.WriteLine(string.Concat(odd.Where(x => x != null)) + " " + string.Concat(even.Where(x => x != null)));

You will also need to change your Console.WriteLine statement at the end to print the elements of the arrays instead of printing the type of the string array.

Console.WriteLine(string.Concat(odd.Where(x => x != null)) + " --- " + string.Concat(even.Where(x => x != null)));

Test Inputs and output

2
abababababababababababababab
abababababababababababababab
bbbbbbbbbbbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaaaaaaaaaaaaaaaa

Alternate Suggestion that doesnt use indexers

foreach (string word in words.Where(x => x != null))
{
    for (int i = 0; i < word.Count(); i++)
    {
        if (i % 2 == 0)
            odd[i] = word[i].ToString();
        else
            even[i] = word[i].ToString();
    }
}
Jawad
  • 9,801
  • 2
  • 18
  • 30