Index Exception that should not exist [duplicate] - c#

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 3 years ago.
So e (this is not a question of what a index out of range exception it is why this specific one is happening when Im using the same index and method some where else Response to recent mark of repetition)
Essentially I am checking to see if a value in the array is Null. But it
keeps giving me an out of range exception when I just used the same
principle
in another area. This may be a silly question with a silly answer but I've
run into the issue and I seem to not be able to solve it.
I have checked that the int going in is correct and that the array is the
correct size.
Im sorry for lack of highlights Im new here and am not sure how to apply
them.` The Place where it goes Wrong
public void OnDragStop()
{
if (SlotHover.name.Contains("Slot"))
{
string[] OS = PSlot.name.Split('t');
int PSN = int.Parse(OS[1]);
string[] NS = SlotHover.name.Split('t');
SN = int.Parse(NS[1]);
Debug.Log(SN);
if (inventory.Inventoryitems[SN] == null)
{
inventory.Inventoryitems[SN] =
inventory.Inventoryitems[PSN];
inventory.Inventoryitems[PSN] = null;
SlotHover.transform.Find("ItemSlotSprite" +
SN).GetComponent<Image>().sprite =
PSlot.transform.Find("ItemSlotSprite" +
PSN).GetComponent<Image>().sprite;
PSlot.transform.Find("ItemSlotSprite" +
SN).GetComponent<Image>().sprite = EmptySprite;
this.gameObject.transform.position = PP;
}
}
}
The Place where its working
public void AddItem(Item ItemToAdd)
{
for(int i = 0; i < inventory.Inventoryitems.Length; i++)
{
if(inventory.Inventoryitems[i] == null)
{
inventory.Inventoryitems[i] = item;
Sprite sprite = ItemToAdd.DefualtSprite;
Inventory.transform.Find("Slot"+i).transform.Find("ItemSlotSprite" +
i).GetComponent<Image>().sprite = sprite;
return;
}
}
}`
IndexOutOfRange: Array index out of range
is what it gives me as shown above Im not sure why in this specific case
its giving the exception.

I think you need to check inventory lenght
if(inventory.Inventoryitems.Length >0){
for(int i = 0; i < inventory.Inventoryitems.Length; i++)
{
if(inventory.Inventoryitems[i] == null)
{
inventory.Inventoryitems[i] = item;
Sprite sprite = ItemToAdd.DefualtSprite;
Inventory.transform.Find("Slot"+i).transform.Find("ItemSlotSprite" +
i).GetComponent<Image>().sprite = sprite;
return;
}
}
}

Related

"Index out of range exception" when index is not out of range [duplicate]

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 2 years ago.
The function shown below is executed many times before it randomly throws the index out of range exception:
public void AddDataT()
{
timeT = SerialPortClass.GetInstance().GetTime();
if (DateTime.Compare(timeT[0], tempTimeT[499]) < 0)
return;
foreach (Series ptSeries in chartT.Series)
{
if (ptSeries.Name == "Temperature 1")
data = SerialPortClass.GetInstance().GetBuffer(5);
else if (ptSeries.Name == "Temperature 2")
data = SerialPortClass.GetInstance().GetBuffer(6);
else return;
indexT = 0;
foreach (float value in data.Latest())
{
AddNewPoint("Temperature", timeT[indexT], value, ptSeries);
tempTimeT[indexT] = timeT[indexT];
indexT++;
}
}
}
As shown in the screenshot, the index at the moment of the exception was 499, and the array size is 500. I know I'm iterating through another buffer based on its size, but both the data and time buffers always have 500 elements. Any idea what might be causing the exception? Here is the code for the AddNewPoint function:
public void AddNewPoint(String chart, DateTime timestamp, float point,
System.Windows.Forms.DataVisualization.Charting.Series ptSeries)
{
if (chart == "Voltage")
scale = scaleV;
else if (chart == "Current")
scale = scaleI;
else scale = scaleT;
ptSeries.Points.AddXY(timestamp, point);
double removeBefore = timestamp.AddSeconds((double)(scale) * (-1)).ToOADate();
while (ptSeries.Points[0].XValue < removeBefore)
{
ptSeries.Points.RemoveAt(0);
}
if (chart == "Voltage")
{
chartV.ChartAreas[0].AxisX.Minimum = ptSeries.Points[0].XValue;
chartV.ChartAreas[0].AxisX.Maximum = DateTime.FromOADate(ptSeries.Points[0].XValue).AddSeconds(scale).ToOADate();
chartV.Invalidate();
}
else if (chart == "Current")
{
chartI.ChartAreas[0].AxisX.Minimum = ptSeries.Points[0].XValue;
chartI.ChartAreas[0].AxisX.Maximum = DateTime.FromOADate(ptSeries.Points[0].XValue).AddSeconds(scale).ToOADate();
chartI.Invalidate();
}
else
{
chartT.ChartAreas[0].AxisX.Minimum = ptSeries.Points[0].XValue;
chartT.ChartAreas[0].AxisX.Maximum = DateTime.FromOADate(ptSeries.Points[0].XValue).AddSeconds(scale).ToOADate();
chartT.Invalidate();
}
}
This doesn't happen all the time, so I'm considering just using a try statement so that the program can keep running when this exception happens occasionally.
On line 210 put a Conditional Breakpoint.
Set the Condition to indexT >= 499
Now debug your code, if you're not sure how to debug watch some video's, it'll take 10-15mins to learn the most handy features.

Unity c# how to compare text from button array with another int array?

i have two arrays. one of ui buttons - with child TextMeshProUGUI and another array of int.
i want to compare each element of button (text) array with int array when all buttons have new value assigned to them.
userInputs[] holds buttons to get user's input from given 8 options to answer question.
correctAnswers[] holds all correct answers.
i am able to check if all buttons got values assigned. then i am checking answers. here i want button image to change green if correct and red if incorrect.
Not able to understand how to compare? please help
public void CheckAnswers()
{
int i = 0;
int j = 0;
// for (i = 0; i < userInputs.Length; i++)
{
foreach (Button userInput in userInputs)
if (userInputs[i].GetComponentInChildren<TextMeshProUGUI>().text
== correctAnswers[j].ToString())
{
userInput.GetComponent<Image>().color = Color.green;
}
else
{
{
userInput.GetComponent<Image>().color = Color.red;
}
}
}
You need to change loops in your CheckAnswers(). You are taking foreach loop for userInputs and still incrementing it with an int It should be like this.
foreach (Button userInput in userInputs)
{
for (i = 0; i < userInputs.Length; i++)
{
if (userInput.GetComponentInChildren<TextMeshProUGUI>().text
== correctAnswers[i].ToString())
{
userInput.GetComponent<Image>().color = Color.green;
}
else
{
{
userInput.GetComponent<Image>().color = Color.red;
}
}
}
}
Becareful because you could get error for Argument out of range exception if your userInputs is less than your correctAnswers array. I hope this helps you.

How to copy one array items to another array in unity Using C#? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have two GameObject arrays with same length. I am trying to copy same values of array1 to array2.
I tried using system.Array.copy(Array1,Array2,4) and also tried Array1= Array2
but not working.
These two arrays are holding 4 buttons each with child text. I want show 4 answers that are assigned to these buttons and copy same answers to another 4 buttons at the same time. Something like dual player.
Can anyone please help?
public class DuelMode : MonoBehaviour{
public static DuelMode instance;
// these are the question values a and b
private int a, b, a1, b1;
//the variable for answer value
[HideInInspector] public int answer;
//varible whihc will assign ans to any one of the 4 answer button
private int locationOfAnswer;
//ref to the button
public GameObject[] ansButtons;
private GameObject[] ansButtonsDuel;
//ref to image symbol so player can know which operation is to be done
public Image mathSymbolObject;
//ref to all the symbol sprites whihc will be used in above image
public Sprite[] mathSymbols;
//get the tag of button
public string tagOfButton;
//ref to text in scene where we will assign a and b values of question
public Text valueA, valueB, valueA1, valueB1;
void Awake()
{
MakeInstance();
}
//method whihc make this object instance
void MakeInstance()
{
if (instance == null)
{
instance = this;
}
}
//at start we need to do few basic setups
void Start()
{
//we put the location value in tag of button variable
tagOfButton = locationOfAnswer.ToString();
MathsProblem();
}
//this method keeps the track of mode
// Update is called once per frame
void Update()
{
tagOfButton = locationOfAnswer.ToString();
}
//Below code is for maths calculation
public void MathsProblem()
{
bool roundActive = true;
}
//this methode perform Multiplication process
void MultiplicationMethod()
{
bool reloop;
bool[] numbers = new bool[301];
b = b1 = Random.Range(1, 10);
locationOfAnswer = Random.Range(0, ansButtons.Length);
answer = a * b;
numbers[answer] = true;
if (valueA != null && valueB != null && valueA1 != null && valueB1 != null)
{
valueA.text = a.ToString();
valueB.text = b.ToString();
valueA1.text = a.ToString();
valueB1.text = b.ToString();
}
mathSymbolObject.sprite = mathSymbols[0];
for (int i = 0; i < ansButtons.Length; i++)
{
if (i == locationOfAnswer)
{
ansButtons[i].GetComponentInChildren<Text>().text = "" + answer;
}
else
{
// the below code make sure that all the values assigned to the ans button are within the range
if (a * b <= 100)
{
ansButtons[i].GetComponentInChildren<Text>().text = "" + Random.Range(1, 101);
}
else if (a * b <= 200 & a * b > 100)
{
ansButtons[i].GetComponentInChildren<Text>().text = "" + Random.Range(101, 201);
}
else if (a * b <= 300 & a * b > 200)
{
ansButtons[i].GetComponentInChildren<Text>().text = "" + Random.Range(201, 301);
}
else if (a * b <= 400 & a * b > 300)
{
ansButtons[i].GetComponentInChildren<Text>().text = "" + Random.Range(301, 401);
}
while (ansButtons[i].GetComponentInChildren<Text>().text == "" + answer)
{
ansButtons[i].GetComponentInChildren<Text>().text = "" + Random.Range(1, 401);
}
}
}
}
}
I assume when you are finished setting texts for ansButtons now you simply want to display the same texts on both sides, right?
for(int i = 0; i < ansButtons; i++)
{
// get the GameObjects
var ansButton = ansButtons[i];
var ansDuelButton = ansButtonsDuel[i];
// get the Text components
var ansText = ansButton.GetComponentInChildren<Text>(true);
var duelText = ansDuelButton .GetComponentInChildren<Text>(true);
// copy the text over
duelText.text = ansText.text;
}
I asume ofcourse you have all the references in ansButtons and ansButtonsDuel setup e.g. via the inspector or while Instantiate the objects.
Please can you post example of your code and the object array. This will help us understand the problem so we can then resolve the issue.
You can also have a look at the post below. It may help your cause.
Difference Between Array.CopyTo() and Array.CloneTo()
EDIT:
var foo = new String[] {"ab" , "cd", "ef"} ;
var bar = new List<string>();
foreach(var item in foo)
{
bar.Add(item);
}
var barArray = bar.ToArray();
for(int i = 0; i < foo.Length; i++)
{
Console.WriteLine(foo[i]);
Console.WriteLine(barArray[i]);
}
The code above makes use of list and arrays since that way you will not have to index your duplicate array. You can run the code in dot net fiddle to see the output. I have used string in this example, please replace with your object.

Is there any way I can make this C# code faster? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am reading in a large file X12 and parsing the information within. I have two bottleneck functions that I can't seem to work around. read_line() and get_element() Is there any way I could make these two functions faster? The main bottleneck in the get_element function seems to be the Substring method.
public String get_element(int element_number) {
int count = 0;
int start_index = 0;
int end_index = 0;
int current_index = 0;
while (count < element_number && current_index != -1) {
current_index = line_text.IndexOf(x12_reader.element_delimiter, start_index);
start_index = current_index + 1;
count++;
}
if (current_index != -1) {
end_index = line_text.IndexOf(x12_reader.element_delimiter, start_index);
if (end_index == -1) end_index = line_text.Length;
return line_text.Substring(start_index, end_index - start_index);
} else {
return "";
}
}
private String read_line() {
string_builder.Clear();
int n;
while ((n = stream_reader.Read()) != -1) {
if (n == line_terminator) return string_builder.ToString();
string_builder.Append((char)n);
}
return string_builder.ToString();
}
I am reading x12 data. Here is an example of what it looks like. http://examples.x12.org/005010X221/dollars-and-data-sent-together/
Since your profiler tells you get_element is a bottleneck, and the method itself is coded very efficiently, you need to minimize the number of times this method is called.
Calling get_element repeatedly in a loop forces it to performs the same parsing job repeatedly:
for (int i = 0 ; i != n ; i++) {
var element = get_element(i);
... // Do something with the element
}
You should be able to fix this problem by rewriting get_element as GetElements returning all elements as a collection, and then taking individual elements from the same collection in a loop:
var allElements = GetElements();
for (int i = 0 ; i != n ; i++) {
var element = allElements[i];
... // Do something with the element
}
in most cases I only need one or two elements
In this case you could make a method that retrieves all required indexes at once - for example, by passing BitArray of required indexes.
Ok, second try. Discarding String.Split due to performance reasons, something like this should work much faster than your implementation:
//DISCLAIMER; typed in my cell phone, not tested. Sure it has bugs but you should get the idea.
public string get_element(int index)
{
var buffer = new StringBuilder();
var counter = -1;
using (var enumerator = text_line.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (enumerator.Current == x12_reader.element_delimiter)
{
counter++;
}
else if (counter == index)
{
buffer.Append(enumerator.Current);
}
else if (counter > index)
break;
}
}
return buffer.ToString();
}
I'm not sure what you are doing exactly, but if I'm understanding your code correctly, wouldn't get element be simpler as follows?
public string get_Element(int index)
{
var elements = line_text.Split(new[] { x12_reader.element_delimiter });
if (index > elements.Length)
return "";
return elements[index];
}

C# For Loop with LIST using LINQ

I'm using LINQ and returning a list to my Business Logic Layer. I'mtrying to change one of the values in the list (changing the 'star' rating to an image with the number of stars).
Although the counter (i) appears to be working, the FOR loop is not working correctly. The first time through it stops at the correct IF but then it pops out at the ELSE statement for everything and all values end up with "star0.png." It appears as though I'm not cycling through the list??? Thanks in advance!
for (int i = 0; i < ReviewList.Count; i++)
{
string serviceCode = ReviewList[i].SERVICE.SERVICE_DESC;
if (serviceCode == "*")
{
ReviewList[i].SERVICE.SERVICE_DESC = "star1.png";
}
else if (serviceCode == "**")
{
ReviewList[i].SERVICE.SERVICE_DESC = "star2.png";
}
else if (serviceCode == "***")
{
ReviewList[i].SERVICE.SERVICE_DESC = "star3.png";
}
else if (serviceCode == "****")
{
ReviewList[i].SERVICE.SERVICE_DESC = "star4.png";
}
else
{
ReviewList[i].SERVICE.SERVICE_DESC = "star0.png";
}
}
If all values end up at star0.png, then you are cycling through the list. The fact that the else statement is the only code being executed for each element suggests a logical error -- did you perhaps mean to do something like this?
string serviceCode = ReviewList[i].SERVICE.SERVICE_CODE;
I dont think its an issue of the for loop working properly... your syntax is good and as written will iterate ReviewList.Count # of times.
I would step through and verify the contents of ReviewList first.
Let me know what you find
If you know each item will consist of a number of stars, why not do this?:
for (int i = 0; i < ReviewList.Count; i++)
{
string serviceCode = ReviewList[i].SERVICE.SERVICE_DESC;
ReviewList[i].SERVICE.SERVICE_DESC = "star" + serviceCode.Length + ".png";
}
Protection on double pass and with else condition
for (int i = 0; i < ReviewList.Count; i++)
{
string serviceCode = ReviewList[i].SERVICE.SERVICE_DESC;
if(!serviceCode.Contains(".png")) { // once name set should not be modified
if(serviceCode.Contains("*"))
ReviewList[i].SERVICE.SERVICE_DESC = "star" + serviceCode.Length + ".png";
else
ReviewList[i].SERVICE.SERVICE_DESC = "star0.png";
}
}
alternate LINQ approach
ReviewList.ForEach(rs=>if(!rs.SERVICE.SERVICE_DESC.Contains(".png"))
{ rs.SERVICE.SERVICE_DESC =
"star" + rs.SERVICE.SERVICE_DESC.Length + ".png"});

Categories