Resetting a char array - c#

I'm having a char array :
public static char[] boardposition = new char[9];
I want to reset the array , my written function for this is:
public static void Reset()
{
Array.Clear(boardposition,9, boardposition.Length);
}
When I call the Reset() I get an exception of type IndexOutOfRangeException.
I hope you guys can help me out.

You are passing 9 as starting index wich isn't a valid index for your array. Make the call like this Array.Clear(boardposition,0, boardposition.Length);

The method Array.Clear takes the following parameters:
Array array - the Array on which the Clear will be performed.
int index - the starting position from which to start clearing
int length - the number of elements which should be cleared.
A bit of test coding covereth a multitude of sins... including sins of misleading or unhelpful documentation.
In your case, the index caused the exception: the last valid position would be Length - 1.
As to the solution: if you intend to clear the entire array while retaining bot initial pointer and array size, the answer is:
Array.Clear(boardposition, 0, boardposition.Length );
If, however, you have no issues with changing the address of the Array, just assign it a new Array with same length; the end result would still be a zeroed Array of length 9:
boardposition = new char[9];
Edit: the best use scenario depends entirely on how boardposition is used later on in the program.

An IndexOutOfRangeException can be raised if the index is smaller than the lower bound of the array, the length is less than zero or if the sum of index and length is greater than the size of array.
In your case the sum of the index and length is (boardposition.Length+9) which exceeds the length of the array and therefore an exception is raised. You need to change your code to:
public static void Reset()
{
Array.Clear(boardposition,0, 9);
}

Related

Index out of range using lists and for loop

I have this loop here, which for each question it is supposed to create, it generates and then formats a 'worded question' from an array of questions, such as; 'What is the sum of {0} + {1}?'. This loop then formats it, adds the worded question and the answer to an array.
// Use for loop to create the correct amount of questions
for (int i = 0; i < Data.Questions.numQuestions; i++)
{
Random rnd = new Random();
Data.Questions.Sum sum = new Data.Questions.Sum();
// Create part one and part two of the question using random numbers
// ex. 3 + 5
// 3 = partOne, 5 = partTwo
int partOne = rnd.Next(Data.Questions.Sum.min, Data.Questions.Sum.max);
int partTwo = rnd.Next(Data.Questions.Sum.min, Data.Questions.Sum.max);
// Randomly select one of the word questions
string fullQuestion = Data.Questions.Sum.wordedQuestions[rnd.Next(0, Data.Questions.Sum.wordedQuestions.Length)];
// Format the string with the generated numbers
fullQuestion = string.Format(fullQuestion, partOne, partTwo);
// Set out-of-class variables to be displayed to the user
Data.Questions.Sum.questions[i] = fullQuestion;
Data.Questions.Sum.answers[i] = partOne + partTwo;
}
Both Data.Questions.Sum.questions and Data.Questions.Sum.answers are List<string>'s and List<int>'s.
However, when this loop is run, with i = 0, I am thrown;
System.ArgumentOutOfRangeException: 'Index was out of range. Must be
non-negative and less than the size of the collection. Parameter name:
index'
Does anyone know what I'm doing wrong? As far as I know lists are dynamic, and I've defined like this;
// Arrays containing all questions and answers
// used to display questions and check answers
public static List<string> questions = new List<string>();
public static List<int> answers = new List<int>();
Also, to clarify, I do not want to use .Add(), as I have a settings panel which when you hit apply, re-runs this loop so the questions are up to date to the current settings. I need the loop to override the previous values.
Edit:
When using arrays, the better option here, I get;
System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'
On assigning Data.Questions.Sum.answers[i], after assigning the array like so; public static int[] answers {};
If you can't .Add() in this lists - create a copy of this lists and .Add() there. Lists has special for that kind of thing: new List<T>(IEnumerable<T>)
If you need to dynamically scale the collection, but you also need to iterate over it multiple times, then you'll need to check whether it is large enough to either insert, or just update.
You can do this with an extension method such as this...
public static class ListExtentions
{
public static void AddOrUpdate<T>(this List<T> that, int index, T value)
{
if (that.Count > index)
{
that[index] = value;
}
else
{
that.Add(value);
}
}
}
...which can then be called like this...
list.AddOrUpdate(index, value);
...however you can make things easier for yourself if you know how many questions you are going to have to start with.
If the number of questions changes when your UI changes, then you will also have to deal with the issue have scaling down the collection to ensure old elements are removed, which is much simpler if you just re-instantiate the collections every time you need to regenerate the questions / answers.
This is likly to be cause of your problem,(I have asked for clarification in comments where you didn't reply).
Still putting this as an answer, as it is potential error spot and you need to fix this.
As you mentioned you are facing this exception on i=0. there are high chanced that this is every time case not any specific case.
If Data.Questions.Sum.questions is empty then, Data.Questions.Sum.questions[i] = fullQuestion; , will surely throw such exception. Same way for Data.Questions.Sum.answers too.
In such case, you must use .Add() to insert into list.
so your code should be,
if (Data.Questions.Sum.questions.Count > i)
Data.Questions.Sum.questions[i] = fullQuestion;
else
Data.Questions.Sum.questions.Add(fullQuestion);
But if they are not empty, it must not be the cause of this exception.
One more thing i have noticed in your code is Data.Questions.Sum.wordedQuestions.
Even if you have valid list (here Data.Questions.Sum.wordedQuestions) - as you have Length prop, it must be Array not list.
If it is empty, while doing this
string fullQuestion = Data.Questions.Sum.wordedQuestions[rnd.Next(0, Data.Questions.Sum.wordedQuestions.Length)];
this line will surely throw
An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
as you are trying to get 0th index's data from it.
So before fetching data from list or array, first you need to check if it does have data init, and also it does have that index which you are asking.
something like
string fullQuestion = string.Empty;
if (Data.Questions.Sum.wordedQuestions != null &&
Data.Questions.Sum.wordedQuestions.Length > 0)
{
//here the way you are creating random number,
// you are assured about index is present in array.
int indexForWordedQuestion = rnd.Next(0, Data.Questions.Sum.wordedQuestions.Length);
fullQuestion = Data.Questions.Sum.wordedQuestions[indexForWordedQuestion];
}

Sorting INT variables C#

I am just beginning with programming in c#;
I got a list of int variables that I want to sort, and find the number 1.
int Weapon_Count1, Weapon_Count2, Weapon_Count3, Weapon_Count4, Weapon_Count5, Weapon_Count6, Weapon_Count7, Weapon_Count8, Weapon_Count9
do I need to do this with an array?
By using the yellow book of C# I found out how to make an array, but I can't figure out how to assign the variables to the array.
int [] Weapon_Count = new int [11] ;
for ( int i=0; i<11; i=i+1)
{
Weapon_Count [i] = ??? ;}
I hope this does make sense..
Please let me explain how to use a C#-array.
This creates an unitialized integer-array with 5 elements:
int[] a1= new int[5];
Assigning values 9,8,7,6 and 5:
(Please note that only indexes from 0 to 4 can be used. Index 5 is not valid.)
a1[0]=9;
a1[1]=8;
a1[2]=7;
a1[3]=6;
a1[4]=5;
The same can also achieved with just one line:
int[] a1= new int[] {9,8,7,6,5};
This might help you.
// Declaring the array
int[] Weapon_Count;
// Initializing the array with a size of 11
Weapon_Count = new int[11];
// Adding values to the array
for (int i = 0; i < Weapon_Count.Length; i++)
{
Weapon_Count[i] = i + 100;
}
// Printing the values in the array
for (int i = 0; i < Weapon_Count.Length; i++)
{
Console.WriteLine(Weapon_Count[i]);
}
// Same thing with a list
// Daclare and initializing the List of integers
List<int> weapon_list = new List<int>();
// Adding some values
weapon_list.Add(1);
weapon_list.Add(2);
weapon_list.Add(3);
weapon_list.Add(4);
weapon_list.Add(5);
// Printing weapin_list's values
for (int i = 0; i < weapon_list.Count; i++)
{
Console.WriteLine(weapon_list[i]);
}
// This is just for the console to wait when you are in debug mode.
Console.ReadKey();
Dont forget to include the using statment if you want to use lists (in short hand - dynamic arrays that can change in size.)
using System.Collections.Generic;
The easiest way to do this, assuming there is a finite list of variables to check, would be to throw them into a temporary array and call either Max() or Min() from the System.Linq namespace.
int maxCount = new int[] { Weapon_Count1, Weapon_Count2, Weapon_Count3, Weapon_Count4, Weapon_Count5, Weapon_Count6, Weapon_Count7, Weapon_Count8, Weapon_Count9 }.Max(); // or .Min()
EDIT
If you still want to get those variables into an array, I would recommend using a System.Collections.Generic.List which has a dynamic size and helper methods such as .Add() to simplify things. Lists can also be used with Linq functions similar to the first part of my answer. See Dot Net Perls for some really good examples on different C# data types and functions.
EDIT 2
As #kblok says, you'll want to add using System.Linq; at the top of your file to gain access to the functions such as Max and Min. If you want to try using the List type, you'll need to add using System.Collections.Generic; as well. If you're in Visual Studio 2017 (maybe 2015 as well?) you can type out the data type and then hit Ctrl + . to get suggestions for namespaces that might contain that data type.
Before we start, you might edit your array to look like this:
int[] weapons = { Weapon_Count1, Weapon_Count2, Weapon_Count3, Weapon_Count4, Weapon_Count5, Weapon_Count6, Weapon_Count7, Weapon_Count8, Weapon_Count9 };
This means that you've created an array called weapons and it is holding integer values.
After you did this, lets find out which element in your array has value of number one.
To find which value has value "1" we must look at each element in array, and we might do that on few ways but I would like recommend foreach or for loop, in this case I will choose foreach loop.
foreach(var item in weapons)
{
if (item == 1)
//Do something
}
This above means, loop throught all of my elements, and in case some of them is equal to number one please do something..
P.S
(I may advice to create one variable which will hold an element which has value '1' and when you find it in a loop assing that variable to that element, and later you can do whatever you want with that variable.. and if you think there will be more elements with value of number one and you need all of them, instead of variable I mentioned above you will create list or array to hold all of your elements and also you can do later with them whatever you want to.)
Thanks and if you are interested in this kind of solution, leave me a comment so let me help you till the end to solve this if you are still struggling.

How to get the length of an array with out empty value?

I'm now doing a project about solving a Magic cube problem. I want to create an array to remember the steps like this:
char[] Steps = new char[200];
Each time I do the 'F','B','R','L','U','D' turn method, it will add a 'F','B','R','L','U','D' character in the array.
But when I want to get the length of the steps, it always shows 200.
for example:
char[] steps = new char[5];
and now I've already added 3 steps:
steps[] = {'f','b','f','',''};
How can I get the length '3'?
Or is there any alternative method I can use that I don't need to set the length at the beginning?
you can just use List<char> but if performance is really critical in your sceanario you can just initialize the initial capacity
something like the following
List<char> list = new List<char>(200);
list.Add('c');
list.Add('b');
here count will return just what you have really added
var c = list.Count;
note in list you can apply Linq Count() or just use the Count property which does not need to compute like Linq and return the result immediately
You will get compilation error on this line
steps[] = {'f','b','f','',''};
As you cannot use empty char and you need to write steps instead of steps[].
I will suggest you to use string array instead and using LINQ get count of not empty elements in this way:
string [] steps = {"f","b","f","",""};
Console.WriteLine(steps.Where(x=>!string.IsNullOrEmpty(x)).Count());
To count non-empty items using System.Linq:
steps.Count(x => x != '\0');
Your code doesn't compile since '' isn't allowed as a char, but I'm assuming that you mean empty elements in a char array which are actually represented by '\0' or the Unicode Null. So the above condition simply counts the non null items in your array.
you could use a list of character that would make things a lot simpler like this :
List<char> steps = new List<char>();
and just add a line to the list for each steps :
char move = 'F';
steps.add(move);
finally then you can count the number of move in the list easily
int numberofmove = steps.count();

Shift items in array up in an array with Array.Copy [duplicate]

This question already has an answer here:
Move/Shift Objects in array up then move the first element to the last index [closed]
(1 answer)
Closed 5 years ago.
Trying to using Array.Copy in the Unity Monodevelop environment, specifically what I'm trying to do is move a value from the first slot of the array into a holder variable, then move every value in the array forward one slot, then move the value from the holder variable back into the Array in the last slot. My relevant code is as follows:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class TurnController : MonoBehaviour {
//Array will hold all units (Being that they all have the EidolonClass script attached), then will be sorted by Speed, descending
private EidolonClass[] AllUnitArray;
...
void Awake(){
//Find anything with the EidolonClass and then add it to the Array
AllUnitArray = FindObjectsOfType (typeof(EidolonClass)) as EidolonClass[];
//Sort the array by speed, descending (Highest speed listed first)
Array.Sort (AllUnitArray, delegate(EidolonClass one, EidolonClass two) {
return two.Speed.CompareTo(one.Speed);
});
}
void pushArray(){
EidolonClass store = AllUnitArray [0];
for(int i=1;i<=AllUnitArray.Length;i++){
Array.Copy (AllUnitArray, i, AllUnitArray, i-1, AllUnitArray.Length-1);
}
AllUnitArray [AllUnitArray.Length] = store;
for(int i=0;i<=AllUnitArray.Length;i++) {
Debug.Log (AllUnitArray[i].name.ToString ());
}
}
void Update () {
if (Input.GetKeyDown (KeyCode.K)) {
pushArray ();
}
}
This code compiles in Monodevelop, but when I try to run this section of my script, it returns the following error:
ArgumentException: length
System.Array.Copy (System.Array sourceArray, Int32 sourceIndex, System.Array destinationArray, Int32 destinationIndex, Int32 length) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Array.cs:971)
TurnController.pushArray () (at Assets/Scripts/Battle Scripts/TurnController.cs:54)
TurnController.Update () (at Assets/Scripts/Battle Scripts/TurnController.cs:37)
Your exception occurs because you are trying to copy the same length multiple times, but with new starting offsets each time. To shift the contents of the array, a single call to Array.Copy() would suffice.
Something like this:
void pushArray(){
EidolonClass store = AllUnitArray [0];
Array.Copy (AllUnitArray, 1, AllUnitArray, 0, AllUnitArray.Length - 1);
AllUnitArray[AllUnitArray.Length - 1] = store;
for(int i=0;i<=AllUnitArray.Length;i++) {
Debug.Log (AllUnitArray[i].name.ToString ());
}
}
That said, an array doesn't seem like the best data structure here, if you want to be able to "shift" the contents. If you were using a Queue<EidolonClass> object, then you could just Dequeue() the first element and then Enqueue() the same element to put it at the back of the list.
Personally, I wouldn't bother with either. Instead of trying to shuffle your data around, just keep an index of which element's turn is current. Increment the index to move to the next element's turn. If you reach the end of the array (i.e. the index value is equal to AllUnitArray.Length), then set the index back to 0.
Actually, the Queue<T> class does exactly that internally anyway. So if you like the semantics of the Queue<T> class, it's about the same implementation-wise.

What is a equivalent of Delphi FillChar in C#?

What is the C# equivalent of Delphi's FillChar?
I'm assuming you want to fill a byte array with zeros (as that's what FillChar is mostly used for in Delphi).
.NET is guaranteed to initialize all the values in a byte array to zero on creation, so generally FillChar in .NET isn't necessary.
So saying:
byte[] buffer = new byte[1024];
will create a buffer of 1024 zero bytes.
If you need to zero the bytes after the buffer has been used, you could consider just discarding your byte array and declaring a new one (that's if you don't mind having the GC work a bit harder cleaning up after you).
If I understand FillChar correctly, it sets all elements of an array to the same value, yes?
In which case, unless the value is 0, you probably have to loop:
for(int i = 0 ; i < arr.Length ; i++) {
arr[i] = value;
}
For setting the values to the type's 0, there is Array.Clear
Obviously, with the loop answer you can stick this code in a utility method if you need... for example, as an extension method:
public static void FillChar<T>(this T[] arr, T value) {...}
Then you can use:
int[] data = {1,2,3,4,5};
//...
data.FillChar(7);
If you absolutely must have block operations, then Buffer.BlockCopy can be used to blit data between array locatiosn - for example, you could write the first chunk, then blit it a few times to fill the bulk of the array.
Try this in C#:
String text = "hello";
text.PadRight(10, 'h').ToCharArray();

Categories