1

I tried to run a program that can read odd and even numbers in an array, but the error that keeps appearing is System.InvalidCastException. Here's the code:

ArrayList Num = new ArrayList();

Console.WriteLine("Enter 5 numbers");

for (int i = 0; 5 > i; i++)
{
    Console.Write((i + 1) + ". ");
    Num.Add(Console.ReadLine());
}

Num.Sort();

Console.Write("Sorted numbers: ");
foreach (string value in Num)
{
    Console.Write(value + " ");
}

Console.ReadLine();

ArrayList odd = new ArrayList();
ArrayList even = new ArrayList();

foreach (int value in Num)
{      
    if (value % 2 != 0)
    {
        odd.Add(value);
    }

    else
    {
        even.Add(value);
    }

}

Console.Write("Odd numbers: ");
foreach (string number in odd)
{
    Console.Write(number + " ");
}

Console.Write("Even numbers: ");
foreach (string numbers in even)
{
    Console.Write(numbers + " ");
}

Console.ReadLine();

The error indicates that my int value code it's value cannot be converted. Can anyone teach me the right way to solve this error?

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76

5 Answers5

4

Ok lets start from the beginning. If you look at the return value of Console.ReadLine then you will see that it returns a string:

Return Value
Type: System.String

ArrayList can contain objects of different types. your code compiles just fine because the Num is masking the differences between the object types.

When you later on try to loop through your ArrayList Num you assume that each element in it is of type int:

foreach (int value in Num)

But it is not! you have filled it with strings. When the compiler arrives at this line it will try implicitly to cast each element into an int (because you told it so) but a simple cast form string to int results in exactly that exception that you have encountered

Several solutions can be approached here....

1)
You could treat the objects in the loop as the type that they are, namely object. Then in each iteration you could try to convert them into an int using TryParse and if the conversion works you can add them into your lists:

foreach (object value in Num)
{
    int intvalue = 0;

    if (Int32.TryParse(value.ToString(), out intvalue)
    {
        if (intvalue % 2 != 0)
        {
            odd.Add(intvalue);
        }
        else
        {
            even.Add(intvalue);
        }
    }
}

2)
Another possibility would be to convert the number right away when you are reading it from the console and to choose a collection that is suitable for the type in question, namely int. For example a generic List

List<int> Num_Int_List = new List<int>();

for (int i = 0; 5 > i; i++)
{
    Console.Write((i + 1) + ". ");
    if (int.TryParse(Console.ReadLine(), out enteredNumber)
    {
        Num_Int_List.Add(enteredNumber);
    }
    else
    {
        Console.WriteLine("Sorry that was not an integer, try again please");
        i-- // here set the counter to the last step to allow the user to repeat the step
    }
}

Use the same collection List<int> for odd and even and you can use your foreach loop as it is:

List<int> odd = new List<int>();
List<int> even = new List<int>();

Choosing a type-safe collection like a List<int> will help you to sort out incompatibilities with types already at compile time and not at runtime like in your case

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
3

I'd suggest you do this like so, parse the number when you read it in, take advantage of the fact that C# is a typed language. Also I'd consider using Generic collections, List and so forth:

List<int> Num = new List<int>();

Console.WriteLine("Enter 5 numbers");

while (Num.Count < 5)
{
    Console.Write((Num.Count + 1) + ". ");

    int result = 0;
    if (int.TryParse(Console.ReadLine(), out result))
    {
        Num.Add(result);
    }
    else
    {
        Console.WriteLine("Please enter a number!!");
    }
}

Num.Sort();

Console.Write("Sorted numbers: ");
foreach (int value in Num)
{
    Console.Write(value + " ");
}

Console.ReadLine();

List<int> odd = new List<int>();
List<int> even = new List<int>();


foreach (int value in Num)
{

    if (value % 2 != 0)
    {
        odd.Add(value);
    }

    else
    {
        even.Add(value);
    }

}

Console.Write("Odd numbers: ");
foreach (int number in odd)
{
    Console.Write(number + " ");
}

Console.Write("Even numbers: ");
foreach (int numbers in even)
{
    Console.Write(numbers + " ");
}


Console.ReadLine();
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
1

as somebody write in the comment section i replace ArrayList with List and then you can Parse your string to int.

Here is my code i hope it helps you.

{

        List<string> Num = new List<string>();


        Console.WriteLine("Enter 5 numbers");

        for (int i = 0; 5 > i; i++)
        {
            Console.Write((i + 1) + ". ");
            Num.Add(Console.ReadLine());
        }

        Num.Sort();

        Console.Write("Sorted numbers: ");
        foreach (string value in Num)
        {
            Console.Write(value + " ");
        }

        Console.ReadLine();

        List<string> odd = new List<string>();
        List<string> even = new List<string>();


        foreach (var value in Num)
        {

            if (Int32.Parse(value) % 2 != 0)
            {
                odd.Add(value);
            }

            else
            {
                even.Add(value);
            }

        }

        Console.Write("Odd numbers: ");
        foreach (string number in odd)
        {
            Console.Write(number + " ");
        }

        Console.Write("Even numbers: ");
        foreach (string numbers in even)
        {
            Console.Write(numbers + " ");
        }


        Console.ReadLine();
    }
Darem
  • 1,689
  • 1
  • 17
  • 37
1

Problem lies with following code:

foreach (int value in Num)
{
    if (value % 2 != 0)
    {
        odd.Add(value);
    }
    else
    {
        even.Add(value);
    }    
}

You are trying to cast string to int directly, which is not possible. There can be many possible solutions, I have mentioned one below, in which I cast using Convert.ToInt32 the string value.

foreach (var value in Num)
{
    if (Convert.ToInt32(value) % 2 != 0)
    {
        odd.Add(value);
    }
    else
    {
        even.Add(value);
    }
}
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
FaizanHussainRabbani
  • 3,256
  • 3
  • 26
  • 46
  • @KamranShahid have a look at the [edit history](https://stackoverflow.com/posts/48782087/revisions) may be someone did not like the first version of it. Why don't you simply change it? – Mong Zhu Feb 15 '18 at 07:27
  • @MongZhu even with the very first version, my answer was correct and didn't deserve a downvote. Downvotes are for wrong answers. – FaizanHussainRabbani Feb 15 '18 at 07:30
  • I am just curious about negative vote. In the history it is not listed who and why negative vote – Kamran Shahid Feb 15 '18 at 07:30
  • @FaizanRabbani "Downvotes are for wrong answers." I guess a lot of people would disagree here with you. personally I prefer to write comments if I think that an answer should be improved instead of downvoting. But from my experience the quality of an answer determines whether the vote goes up or down. 1) Explanation of why the error arose in the first place, 2) quality of the presented solution 3) description and explanation of the presented solution and 4) teaching efforts are possible criteria to get upvotes – Mong Zhu Feb 15 '18 at 07:42
  • 1
    @KamranShahid I am also always curious, " In the history it is not listed who and why" no it is not, you are right. A lot of people don't care to leave the reasons of their downvote. – Mong Zhu Feb 15 '18 at 07:44
  • 1
    @MongZhu thank you for the tips for writing an answer, I will keep those points in mind next time if I answer a question. – FaizanHussainRabbani Feb 15 '18 at 08:00
0
ArrayList Num = new ArrayList();

Console.WriteLine("Enter 5 numbers");

for (int i = 0; 5 > i; i++)
{
    Console.Write((i + 1) + ". ");
    Num.Add(Console.ReadLine());
}

Num.Sort();

Console.Write("Sorted numbers: ");
foreach (string value in Num)
{
    Console.Write(value + " ");
}

Console.ReadLine();

ArrayList odd = new ArrayList();
ArrayList even = new ArrayList();
int V;
foreach (string value in Num)
{
    V = int.Parse(value);
    if (V % 2 != 0)
    {
        odd.Add(value);
    }
    else
    {
        even.Add(value);
    }
}

Console.Write("Odd numbers: ");
foreach (string number in odd)
{
    Console.Write(number + " ");
}

Console.Write("Even numbers: ");
foreach (string numbers in even)
{
    Console.Write(numbers + " ");
}

Console.ReadLine();

Please do it.