Object reference not set to an instance of an object EDIT - c#

I'm new here and I tried looking through old questions but I am new to c# as well, and I am finding it difficult to solve my problem below:
if (File.Exists(#"C:\ESC\Impostazioni.txt"))
{
TextReader lettore_file = new StreamReader(#"C:\ESC\Impostazioni.txt");
String opzioni = lettore_file.ReadLine();
int i;
for (i = 0; i < opzioni.Length; i++) <----here, indicating "i=0"
{
if (opzioni[i] == '-')
{
char[] coloregenerale = new char[i];
for (int j = 0; j < i; j++)
coloregenerale[j] = opzioni[j];
break;

You should put a check to see if the string value is null or empty before trying to loop through each character, like this:
if(!String.IsNullOrEmpty(opzioni))
{
// Put loop through character logic here
}

You need to debug through and find out if your opzioni string is a null reference after your call to String opzioni = lettore_file.ReadLine();
Also, you should probably declare i within the for loop, instead of before it, like shown below.
for (int i = 0; i < opzioni.Length; i++)

There are several wrongs inside that code:
You're missing a using statement.
You're not checking the result of StreamReader.ReadLine.
It looks like you're reimplementing string.Substring.
Sample:
if (File.Exists(#"C:\ESC\Impostazioni.txt"))
{
using (var letterFile = new StreamReader(#"C:\ESC\Impostazioni.txt"))
{
var opzioni = letterFile.ReadLine();
if(string.IsNullOrWhiteSpace(opzioni))
{
// end of file
}
var dashIndex = opzioni.IndexOf("-");
string coloregenerale = dashIndex > -1
? opzioni.Substring(0, dashIndex)
: opzioni;
}
}

If your null reference exception is occurring on the indicated line, the culprit is probably the opzioni variable. If the earlier call to lettore_file.ReadLine() returns null, opzioni will be null when you try to get it's length in the for loop. That will throw the exception you're experiencing. A solution is to check that variable for null before entering the loop

The opzioni may have the chances of null value on that particular index, better handle inside of that line with IsNullorEmpty Condition
char[] coloregenerale = new char[i];
for (int j = 0; j < i; j++)
{
if( String.IsNullOrEmpty(opzioni[j] == false ) // This is mandatory check at this place
coloregenerale[j] = opzioni[j];
}

Related

Can I have an if statement change what variable is accessed in a loop

Hey I'm in a situation where I have a for loop that does some stuff and I want to make a line of code either call a function passing in an array indexed by the for loops index, or run a single (not array) variable for every call of that function, I know I could do that by putting an if statement inside the for loop but i'd be repeating the same if statement over and over getting the same result. So is there a way good way I can run the if statement before the for loop and the result of that if statement run the same for loop but that one call passes in the array or the variable?
Code Example
for (int i = 0; i < CurrentVerticalList.Count; i++)
{
GuiGeneral CGroup = CurrentVerticalList[i];
CGroup.ResizeUsingStandard(ForcedResize[i]); //I want the condition before the for
//loop to have ForcedResize[i] here if
//true and another variable here of the
//same type but not an array if false.
for (int j = 0; j < 2; j++)
{
GlobalListIndex[j]++;
}
CGroup.MoveElementTo(CCoord, false);
CCoord.y += CGroup.ElementRect.WidthHeight.y;
}
Here you go, moving your condition check out of your for loop:
Func<int, double> GetResizeFromForcedResize = (index => ForcedResize[index]);
Func<int, double> GetResizeFromVariable = (index => fixVariable);
var GetResizeValue = condition? GetResizeFromForcedResize : GetResizeFromVariable;
for (int i = 0; i < CurrentVerticalList.Count; i++)
{
GuiGeneral CGroup = CurrentVerticalList[i];
CGroup.ResizeUsingStandard(GetResizeValue(i));
for (int j = 0; j < 2; j++)
{
GlobalListIndex[j]++;
}
CGroup.MoveElementTo(CCoord, false);
CCoord.y += CGroup.ElementRect.WidthHeight.y;
}
Edit: Wanted to let you know that the other answers here are still doing a check at every iteration, but not this one.
Eh, hard to understand the question to me but i recon what you want is something along these lines, could've helped with more types supplied, but you could make the intend achievable using a local function:
ForcedResizeArrayType other = new object(); //TODO: Define return type
bool condition = ResolveCondition(); //TODO: Define condition to be true or false
ForcedResizeArrayType GetOneOr(int i, bool condition,
ForcedResizeArrayType[] forcedResizeArray)
{
return condition ? forcedResizeArray[i] : other;
}
for (int i = 0; i < CurrentVerticalList.Count; i++)
{
CGroup.ResizeUsingStandard(GetOneOr(i, condition, ForcedResize));
}
It varies from week to week if i love or hate those local functions, but they have uses

How to fix the output after I compare two arrays in C#?

So I have this homework assignment that requires me to assign output to labels after I compare two arrays. My problem is that after I compare the two arrays, the output I assign is wrong. I'm supposed to out 'Y' if at a specific index of the two arrays are equal and 'N' if they're not equal but every time I run the code, it outputs 'Y' to all the labels no matter what. How can I fix what is being outputted after the comparison?
private void evaluateStudentAnswers()
{
/* Use a "for" loop to cycle through the answerKey[] and studentAnswers[] arrays, and compare the answers
* in the two arrays at each index. If they match, then increment the global variable "correctAnswers"
* and assign the value 'Y' to the corresponding index in the correctOrIncorrect[] array. if they
* don't match, then increment the global variable "incorrectAnswers" and assign the value 'N' to the
* corresponding indes in the correctOrIncorrec[] array. These two variables will be used to calculate
* the grade percentage.
*/
for (int i = 0; i < studentAnswers.Length; i++)
{
for(int j = 0; j < answerKey.Length; j++)
{
// I think the indexes below are being checked if they're the same and I need to make sure not just the
//indexes are the same but the values as well
if (studentAnswers[i] == answerKey[j])
{
correctAnswers++;
for(int k = 0; k < correctOrIncorrect.Length; k++)
{
correctOrIncorrect[k] = 'Y';
}
}
else
{
incorrectAnswers++;
for (int k = 0; k < correctOrIncorrect.Length; k++)
{
correctOrIncorrect[k] = 'N';
}
}
}
}
}
I think your code can be simplified quite a lot. assuming there's a 1-1 mapping between studentAnswers and answerKey.
for (int i = 0; i < studentAnswers.Length; i++)
{
var studentAnswer = studentAnswers[i];
var answer = answerKey[i];
if (studentAnswer == answer)
{
++correctAnswers;
correctOrIncorrect[i] = 'Y';
}
else
{
++incorrectAnswers;
correctOrIncorrect[i] = 'N'
}
}
All of the arrays are the same size. So when we loop over each answer the student provided, we know we can find the corresponding correct answer in answerKey. Also, the tracking of correct answers also follows the same pattern, for each studentAnswer, we want to record the correctness in correctOrIncorrect, which corresponds to the particular answer the student provided. As such, we only need to perform a single loop, since the i refers to the appropriate index in all the arrays as we're processing.
If studentAnswers.Length == answerKey.Length == correctOrIncorrect.Length
Then
for (int i = 0; i < studentAnswers.Length; i++)
{
if(studentAnswers[i] == answerKey[j])
{
correctAnswers++;
correctOrIncorrect[k] = 'Y';
}
else
{
incorrectAnswers++;
correctOrIncorrect[k] = 'N';
}
}
Since it is an assignment I wont give an answer :) but since you are stuck I encourage you use the guidance below.
These two are unnecessary in your code
inner for-loop on correctOrIncorrect[]
variable "k", you can use "i" instead for correctOrIncorrect value assignment
Since the arrays have to have the same size/order, you only need to loop through them once. Also I find ternary assignments more clear than if blocks:
Func<bool, int> toInt = (b) => b ? 1 : 0;
for (int i = 0; i < studentAnswers.Length; i++)
{
var studentAnswer = studentAnswers[i];
var answer = answerKey[i];
var isCorrect = studentAnswer == answer;
correctOrIncorrect[i] = isCorrect ? 'Y' : 'N';
correctAnswers = isCorrect ? 1 : 0; // toInt(isCorrect)
incorrectAnswers = !isCorrect ? 1 : 0; // toInt(!isCorrect)
}
}
Or in LINQ (just because it's worth learning, but probably not appropriate for homework):
correctOrIncorrect = answerKey.Zip(studentAnswer, (a,b) => a == b ? "Y" : "N").ToArray();
incorrectAnswers = correctOrIncorrect.Count(x => x == "Y");
...

Write a character at the end of an array

Here's my code:
for (int j = 0; j < bufferreader.Length; j++)
{
using (StreamWriter sw = File.AppendText(#"C:\Users\yamald\Documents\Normal.data"))
{
//sw.Write();
if (bufferreader.length != null)
{
sw.Write(bufferreader[j] + ",");
}
else
{
sw.WriteLine("\n");
}
}
}
How can I write a "\n" at the end of array to my file? The else command does not run.
You need to place sw.WriteLine("\n"); after the for loop.
As the loop stops when j = bufferreader.length, the if statement is always true.
Also, I think that bufferreader.length will never be null as you never modify this variable. I think what you need is :
if (bufferreader.length > j)
You should probably just make the StreamWriter object before everything else and have it available until the loop has finished, then just write the newline after the loop, like this:
using (StreamWriter sw = File.AppendText(#"C:\Users\yamald\Documents\Normal.data"))
{
for (int j = 0; j < bufferreader.Length; j++)
{
sw.Write(bufferreader[j] + ",");
}
sw.WriteLine("\n");
}
It's also probably better to use a while loop and do something like while(bufferreader.length != null) instead of the for loop and if statement, but that's up to you and I haven't used bufferreader in a while so wouldn't know the exact syntax for that.
However, the reason for why the else never gets executed is (as EoiFirst correctly said) that you're not actually changing bufferreader.length so it won't ever be null.

passing arrays in c#

Hi i am working on Grade Calculation. My problem here is if the length of string array is longer that int array it works skipping the last 2 grades.
ex:
int[] unit = new int[] {1,-3,3,4};
string[] letter_grade = new string[] {"A", "B","B","W","D","F"};
but if length of int array longer than that of string array its not working its throwing error Index was outside the bounds of the array.
int[] unit = new int[] {1,-3,3,4,5,6,7};
string[] letter_grade = new string[] {"A", "B","B"};
so my question how do i make it work for both??
int length = unit.Length;
int no_units = length;
double totalGrade_Points = 0.0;
int totalno_units = 0;
totalGPA = 0;
for (int i = 0; i < unit.Length; i++)
{
entrygot = findGpaListentry(letter_grade[i]); //Index was outside the bounds of the array.
if (entrygot != null)
{
//some code calculation
}
}
For array indexing you must have starting and stopping condition defined very well. For accessing two arrays either they must be equal or they are compared under certain valid conditions. Have a look at this:
for(int i=0;i<unit.length;i++){
entrygot = findGpaListentry(letter_grade[i]);// only if letter_grade is valid under all values of i i.e unit.length
}
// either you have to check as if;
if(lenght_of_letter_grade < i-1)
//then access
entrygot = findGpaListentry(letter_grade[i]);
You can't just check if the array item is null, because you would be out of the bounds of the array and you will get an exception before the null check occurs.
I would check the length of the array on each iteration...
for (int i = 0; i < unit.Length; i++)
{
if (currentArray.Length < i - 1) { break; }
// other code...
}
I think in your case, the number of elements will never be large hence performance wont be an issue. So I think you should be using a List instead of an array. With an array you will have to be insert checks each time some logic changes or you add other functionalities.
foreach loop is best for your scenerio.
foreach (string s in letter_grade)
{
entrygot = findGpaListentry(s);
if (entrygot != null)
{
//some code calculation
}
}

Anonymous c# delegate within a loop

Hi all i am trying to write and anonymous delegate. as the integer variable is shared among the delegate i need it to be the local instance of every delegate such that rs[0] always gets nics[0], rs[1] always gets nics[1] and so on... how will i achieve this.
for (int i = 0; i < nics.Count; i++)
{
rs[i] = new RollingSeries(monitor, new RollingSeries.NextValueDelegate(delegate()
{
return GetNetworkUtilization(nics[i]);
}));
}
Abdul khaliq
Make a local copy of i:
for (int i = 0; i < nics.Count; i++)
{
int j = i;
rs[i] = new RollingSeries(monitor, new RollingSeries.NextValueDelegate(delegate()
{
return GetNetworkUtilization(nics[j]);
}));
}
The Beauty of Closures
Use a local to get a different value per iteration
for (int i = 0; i < nics.Count; i++)
{
int localI = i;
rs[i] = new RollingSeries(monitor, new RollingSeries.NextValueDelegate(delegate()
{
return GetNetworkUtilization(nics[localI]);
}));
}
Put int j = i inside your loop and refer to j within the lambda expression.
If you are curious about why this happens, here is an MSDN blog entry containing a detailed technical explanation: Closing over the loop variable considered harmful

Categories

Resources