-1

I am trying to write a C# program that will convert Roman numbers to Integer.

I get index outside of bounds of the array error when I try short inputs.

When I try long input like = "MCMXIV" (it equals to 1994) I get exactly 1994 as result.

But when I try shorter input like "III", I get Index outside of bounds of the array error.

Can you check my code and tell me where did I make mistake? Thanks.

using System;
                    
public class Program
{
    public static void Main()
    {
        Console.Write("Input:");
        string s = Console.ReadLine();
        int print = RomanToInt(s);
        
        Console.WriteLine($"Result is: {print}");
        
        static int RomanToInt(string s) 
        {    
            
                int [] decimalValues = new int[7]  { 1,  5, 10, 50, 100, 500, 1000};       
        
                int [] inputValues = new int[s.Length];
        
                for (int i = 0; i < s.Length; i++)
                {
                        if (s[i] == 'I')
                        {
                            inputValues[i] = decimalValues[0];
                        }
                        else if (s[i] == 'V')
                        {
                            inputValues[i] = decimalValues[1];
                        }
                        else if (s[i] == 'X')
                        {
                            inputValues[i] = decimalValues[2];
                        }
                        else if (s[i] == 'L')
                        {
                            inputValues[i] = decimalValues[3];
                        }
                        else if (s[i] == 'C')
                        {
                            inputValues[i] = decimalValues[4];
                        }
                        else if (s[i] == 'D')
                        {
                            inputValues[i] = decimalValues[5];
                        }
                        else if (s[i] == 'M')
                        {
                            inputValues[i] = decimalValues[6];
                        }
                }
        
       
                int [] inputValuesAfter = new int[s.Length];

                for (int i = 0; i < inputValues.Length; i++)
                {
                    if (inputValues[i] >= inputValues[i+1])
                    {
                        inputValuesAfter[i] = inputValues[i];
                    }
                    else if (inputValues[i] < inputValues[i+1])
                    {
                          inputValuesAfter[i] = inputValues[i+1] - inputValues[i];
                          i++;
                    }   
                }
            
                int result = 0;
        
                for (int i = 0; i < (inputValuesAfter.Length); i++)
                {
                    result += inputValuesAfter[i]; 
                }
             
                return result;
        }
    }
}
yusufukr
  • 1
  • 1
  • Which line gives the exception? What's the value of the indexer and the contents of the array when the exception is thrown? – gunr2171 Oct 30 '22 at 23:03
  • Duplicate: [What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?](https://stackoverflow.com/questions/20940979/what-is-an-indexoutofrangeexception-argumentoutofrangeexception-and-how-do-i-f) – Ňɏssa Pøngjǣrdenlarp Oct 30 '22 at 23:17
  • You increment the ‘for’ control variable’i’ inside the loop. Aside: you should learn about the ‘switch’ statement. – 500 - Internal Server Error Oct 30 '22 at 23:18
  • You are failing on line : "if (inputValues[i] >= inputValues[i + 1])" When you enter "iii" as input is length 3. So 'i' goes from 0 to 2 (length 3). But you are indexing "i + 1". So when 'i' is 2 then 'i + 1' is 3 which give the exception since the length of the array is 3 (0 to 2). So either the for loop needs to be 0 to (inputValues.Length - 1) or you need to change the for loop to start at 1 and then change if to : if (inputValues[i - 1] >= inputValues[i]) – jdweng Oct 30 '22 at 23:23

1 Answers1

2

When your second-to-last inputValues element is not less than the last inputValues element, inputValues[i+1] is evaluated for the final i value (i.e., inputValues.Length - 1), that results in i + 1 == inputValues.Length and an index out of bounds exception. What you need to do is handle the special case of working with the final element of inputValues. One way to do so is to add such a test to that first if condition:

var nextOffset = i + 1;

if( inputValues.Length == nextOffset
    || inputValues[i] >= inputValues[nextOffset] )
{
    inputValuesAfter[i] = inputValues[i];
}
else // `if` condition isn't needed here
{
    inputValuesAfter[i] = inputValues[nextOffset] - inputValues[i];
    ++i;
}
Moho
  • 15,457
  • 1
  • 30
  • 31