NullReferenceException? Why? [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I try to calculate the total collective age of my passengers in calc_total_age() this works before I add a passenger and writes out "0". However when I add a passenger I get NullReferenceException, I have tried different things but I just can't wrap my head around what I'm doing. I need a little shove in the right direction and maybe and explanation of what the he** I am doing and I don't know what my GetAge() does either really I have tried to call it but it doesn't seem to work.
This is all my code:
using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
class Program {
public static void Main (string[] args) {
//Console.Clear();
Console.WriteLine("Hi, welcome to the Buss-Simulator!");
Console.ReadKey();
var mybus = new Bus();
mybus.Run();
Console.ReadKey();
}
}
using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
class Bus {
public int total_passengers = 0;
public Passenger[] info_passengers;
public int totalAge = 0;
public int totalSeats = 25;
public void Run()
{
info_passengers = new Passenger[25];
string [] menu = new string[]{"1. Pick up passenger.", "2. Show who's on the bus.", "3. Calculate total age of passengers"};
int MenuSelect = 0;
while (true)
{
Console.Clear();
Console.WriteLine("What do you want to do?");
Console.WriteLine();
Console.CursorVisible = false;
if (MenuSelect == 0)
{
Console.WriteLine(menu[0] + " ⭅");
Console.WriteLine(menu[1]);
Console.WriteLine(menu[2]);
}
else if(MenuSelect == 1)
{
Console.WriteLine(menu[0]);
Console.WriteLine(menu[1] + " ⭅");
Console.WriteLine(menu[2]);
}
else if(MenuSelect == 2)
{
Console.WriteLine(menu[0]);
Console.WriteLine(menu[1]);
Console.WriteLine(menu[2] + " ⭅");
}
var keyPressed = Console.ReadKey();
if(keyPressed.Key == ConsoleKey.DownArrow && MenuSelect != menu.Length -1)
{
MenuSelect++;
}
else if (keyPressed.Key == ConsoleKey.UpArrow && MenuSelect >= 1)
{
MenuSelect--;
}
else if (keyPressed.Key == ConsoleKey.Enter)
{
switch (MenuSelect)
{
case 0:
add_passengers();
break;
case 1:
print_passengers();
break;
case 2:
calc_total_age();
break;
}
}
}
}
public void add_passengers()
{
if (total_passengers == 25)
{
Console.WriteLine("\nBus is full!");
System.Threading.Thread.Sleep(2000);
return;
}
try
{
Console.WriteLine("\nType the name, age & gender of your passenger.");
Console.Write("\nName: ");
string name = Console.ReadLine();
Console.Write("\nAge: ");
int age = Convert.ToInt32(Console.ReadLine());
Console.Write("\nGender: ");
string gender = Console.ReadLine();
Passenger passenger = new Passenger(aName: name, aAge: age, aGender: gender);
Array.Resize(ref info_passengers, info_passengers.Length + 1);
info_passengers[info_passengers.Length - 1] = passenger;
}
catch (Exception e)
{
Console.WriteLine("\nFollow instructions.");
System.Threading.Thread.Sleep(2000);
return;
}
total_passengers++;
Console.WriteLine("You boarded 1 Passenger." + "\nThere are " + (totalSeats - total_passengers) + " seats left.");
System.Threading.Thread.Sleep(2000);
return;
}
public void print_passengers()
{
Console.WriteLine();
foreach (var i in info_passengers)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
public void calc_total_age()
{
for (int i = 0; i < total_passengers; i++)
{
totalAge += info_passengers[i].age;
}
Console.WriteLine(totalAge);
Console.ReadKey();
}
}
using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
class Passenger{
public string name;
public int age;
public string gender;
public Passenger(string aName, int aAge, string aGender)
{
name = aName;
age = aAge;
gender = aGender;
}
public override string ToString()
{
return string.Format($"This is {name}, {gender}, {age} years old.");
}
public int GetAge()
{
return age;
}
}

you don't need to resize info_passengers array since it is enough for total passangers. When you add an extra array cell, you add a passanger to the end of arry, but you still have the empty cells in the beginnig of array with null that are causing the exception.
so remove this code
Array.Resize(ref info_passengers, info_passengers.Length + 1);
and fix this
total_passengers++;
info_passengers[ total_passengers-1] = passenger;
and don't forget to remove total_passengers++; from here
Console.WriteLine("You boarded 1 Passenger." + "\nThere are " + (totalSeats - total_passengers) + " seats left.");
and add totalAge=0 in calc_total_age
public void calc_total_age()
{
totalAge=0;
for (int i = 0; i < total_passengers; i++)
{
totalAge += info_passengers[i].age;
}
and it is not a very good idea to hide errors in your catch blok. I would make it
catch (Exception e)
{
Console.WriteLine("\n Error!!! " + e.Message);
System.Threading.Thread.Sleep(2000);
return;
}

The answer to this one is very simple!
You declare:
public Passenger[] info_passengers;
This actually creates a pointer to a Passenger array, which (like all pointers) is initially null. It does not create the actual array itself.
When your code comes to call:
Array.Resize(ref info_passengers, info_passengers.Length + 1);
the method Resize expects the array parameter to point to an array. However, info_passengers is still null. So you get the exception.
I think all you need to do is to initialise info_passengers to an new empty array, like this:
public Passenger[] info_passengers = new Passenger[]();
and then I think it'll all work.

Related

C# Sliding Window Algorithm

So i have to sent a message from a Sender to a Destination(Shown in main class) by specifing how many letters i wanna sent (the size variable).When the laters left are less than letters i wanna sent,it automaticaly sent how many i have left,and after the algorithm stops;
The problem is when the message i supossely sent is 9 characters long,and when i wanna sent 6 characters and another 3 it throws me an error (System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'
)
using System;
using System.Text;
using System.Threading;
namespace homework
{
internal class slidingWindow
{
private string name;
private StringBuilder message = new StringBuilder();
private bool isSource = false;
private int fin = 0;
public slidingWindow(string name, bool isSource)
{
this.name = name;
this.isSource = isSource;
}
public void messageSet(string _message)
{
if (isSource == true) message.Append(_message);
else Console.WriteLine("Is not source");
}
public void sendMessage(slidingWindow destination)
{
int counter= 0;
Console.WriteLine("Specify the size of data sent: ");
int size = Convert.ToInt32(Console.ReadLine()); //the size of how manny letters i should send
int countCharacterSent=size;
for (int x = 0; x < message.Length+(message.Length%size); x = x + size)
{
counter++;
for (int y = 0; y < size; y++)
{
if (x + size > message.Length + (message.Length % size)) { size=size-(message.Length%size); countCharacterSent = message.Length; }
else {destination.message.Append(message[x + y]); }
}
Console.WriteLine("Sennder---- " + destination.message + " ----->Destination" + " (" + counter+ ")"+ " Characters sent: "+size+ " Characters received: "+countCharacterSent+ '\n');
Thread.Sleep(TimeSpan.FromSeconds(1));
countCharacterSent = countCharacterSent + size;
}
fin = 1;
if (message.Length % size != 0) destination.fin = 1;
destination.print();
}
public void print()
{
Console.WriteLine("Destination has receveid the message: " + message+" FIN: "+fin);
}
}
and the main class
using System;
namespace homework
{
class main
{
static void Main(string[] args)
{
while (true)
{
int option = 0;
slidingWindow a = new slidingWindow("Sender", true);
a.messageSet("exampless");
slidingWindow b = new slidingWindow("Destination", false);
a.sendMessage(b);
Console.WriteLine("If you want to exit write 1:"+'\n');
option = Convert.ToInt32(Console.ReadLine());
if (option == 1) break;
}
}
}
example:
input:
message='example'
size=3;
output:
exa
mpl
e
Honestly I can see you try hard (too hard) to handle the limit case of the last block that can just not meet the expect size.
Since you do this in dotnet C#, and depending on the version you will see you have many different options....
Especially to create a batch of x out of a simple sequence....
here is a homemade version of things you will find for free in libraries like moreLinq and probably in latest Linq lib..
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
public static class LinqExtensions
{
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source, int size)
{
return source
.Select( (c, i) => (c, index : i))
.Aggregate(
new List<List<T>>(),
(res, c) =>
{
if (c.index % size == 0)
res.Add(new List<T> { c.c });
else
res.Last().Add(c.c);
return res;
});
}
}
public class Program
{
public static void Main(string[] args)
{
var test = "xxxxxxxxxxx".AsEnumerable();
var blocks = test
.Batch(3)
.Select(b=> new string(b.ToArray()));
blocks.ToList().ForEach(System.Console.WriteLine);
}
}

How to determine input when the can have a variable?

I'm working on this commandline based dice. And I want it to be able to output statistics and reset those internal statistics. Currently I have the following classes: Dice and DiceInterface.
I want the user to be able to use the following format for input: "'Throw' to throw the dice, alternate use 'Throw(x)', 'Stat(side)' to see how many times (side) has been thrown, or 'Reset' to reset thrown statistics"
I need a way to determine if the user has typed Throw, Throw(x), Stat(side) or Reset. Throw and Reset are obvious to me but I find it quite difficult to imagine a way to do Throw(x) and Stat(side). Does anyone have any tips or a solution?
Thanks in advance!
using System;
using System.Collections.Generic;
using System.Text;
namespace Oefening_2
{
class DiceInterface
{
static void Main()
{
StartProgram();
}
static void StartProgram()
{
Console.WriteLine("Hello, how many sides would you like the dice to have?");
var input = Console.ReadLine();
if (Int32.TryParse(input, out int number))
{
int desiredSides = number;
Dice NewDice = new Dice(desiredSides);
Console.WriteLine("What would you like to do? ");
Console.WriteLine("Type: 'Throw' to throw the dice, alternate use 'Throw(x)', 'Stat(side)' to see how many times (side) has been thrown, or 'Reset' to reset thrown statistics");
MainIO(NewDice);
}
else
{
Console.WriteLine("That is not an integer! The program will restart now...");
StartProgram();
}
}
static void MainIO(Dice CurrentDice)
{
Console.Write("Input: ");
string input = Console.ReadLine();
//Throw
if (input == "Throw")
{
Console.WriteLine(CurrentDice.Throw());
MainIO(CurrentDice);
}
//Throw(x)
else if(input == "")
//Thrown(side)
//Reset
else if (input == "Reset")
{
CurrentDice.ResetStatistics();
MainIO(CurrentDice);
}
}
}
}
using System;
namespace Oefening_2
{
class Dice
{
public int Sides { get; set; }
private readonly Random _rnd = new Random();
public int[] Thrown;
public Dice(int sides)
{
Sides = sides;
Thrown = new int[sides--];
}
public Dice():this(6)
{
}
public int Throw()
{
int thrownNumber = _rnd.Next(1, Sides);
Thrown[thrownNumber]++;
return thrownNumber;
}
public int NrOfTimesThrown(int side)
{
int result;
result = Thrown[side];
return result;
}
public void ResetStatistics()
{
for(int i = 0 ; i < Sides; i++)
{
Thrown[i] = 0;
}
}
}
}
This can be fairly simply done with StartsWith to check if a string starts with some prefix, and use .Remove to get anything after this prefix:
if(input.StartsWith("Stat"){
var parameterString = input.Remove(0, "Stat".Length);
if(int.TryParse(parameterString , out var side){
...
}
}
If I correctly understood your problem, it could be solved with an approach like this:
Console.WriteLine("Enter a value");
var s = Console.ReadLine();
if(s.Contains('('))
{
int pFrom = s.IndexOf("(");
int pTo = s.LastIndexOf(")");
var myChoice = s.Substring(0, pFrom);
var myValue = s.Substring(pFrom + 1, pTo - pFrom);
Console.WriteLine($"You choosed : {myChoice}");
Console.WriteLine($"With a value of: {myValue}");
}
This is just a brief example of how to "understand" if there is a value and then recover it.
I hope this could help you somehow.

Linked list implementation of array using c# console

Hi i was wondering if anyone could help me. im stuck in a dead end here. I dont know how to make a peek and working pop function. i need assistance.
here is my code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp13
{
class Program
{
int nextFree;
int End;
int Start;
Names[] Stack;
Names steven = new Names();
Names jacques = new Names();
Names samantha = new Names();
Names lilly = new Names();
public struct Names
{
public Int32 pointer;
public string data;
}
static void Main(string[] args)
{
Program prog = new Program();
do
{
prog.DisplayMenu();
}
while (true);
}
public void DisplayMenu()
{
Int32 userInput = 0;
Console.WriteLine("Enter number of choice:");
Console.WriteLine("=======================");
Console.WriteLine("1: Sign up for consultation");
Console.WriteLine("2: Begin consultation");
Console.WriteLine("3: Enter room");
Console.WriteLine("4: Closing time");
Console.WriteLine("5: Exit");
userInput = Int32.Parse(Console.ReadLine());
switch (userInput)
{
case 1:
this.Push();
break;
case 2:
this.Pop();
break;
case 5:
System.Environment.Exit(1);
break;
}
}
public Program()
{
Stack = new Names[20];
steven.data = "Steven";
steven.pointer = 1;
jacques.data = "Jacques";
jacques.pointer = 2;
samantha.data = "Samantha";
samantha.pointer = 3;
lilly.data = "Lilly";
lilly.pointer = -1;
Stack[0] = steven;
Stack[1] = jacques;
Stack[2] = samantha;
Stack[3] = lilly;
nextFree = 4;
End = 20;
Start = 0;
}
public string Pop()
{
string value = string.Empty;
if (nextFree == -1)
{
Console.WriteLine("Stack is empty");
Console.ReadLine();
}
else
{
Names thisNode = Stack[End];
int temp = End;
End = thisNode.pointer;
thisNode.pointer = nextFree;
nextFree = temp;
}
this.ListAllNames();
return value;
}
public void Push()
{
if (nextFree >= Stack.Length)
{
Console.WriteLine("Stackoverflow, to many elements for the stack");
Console.ReadLine();
}
else
{
Console.WriteLine("Enter a name to be added");
string input = Console.ReadLine();
Stack[nextFree].data = input;
Stack[nextFree].pointer = End;
End = nextFree;
nextFree++;
}
this.ListAllNames();
}
public void ListAllNames()
{
foreach (Names name in Stack)
{
Console.WriteLine("Name:" + name.data);
}
}
}
}
as you can see it is unfinished. im at a standstill and cannot move one.
I have trouble in using the elements here so that i could make a function such as peek and pop properly.

C# Console.WriteLine not printing in one line

Now if you run this it does not output each Console.WriteLine in one line, why?
I know console.writeline goes to next line when done but the problem is it jumps to next line while printing when it print the exception var it is not in the same line as the rest of the writeline
The error occurs inside the Display() function at the number 6 variable (exception) it is not in the same line as the rest of the writeline, why?
And also there are no line breaks where the error ocurs.
Ans can be any number you like.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace EquationSolver
{
class Program
{
public static string exception = "No Solution Found yet";
public static int go = 40;
public static Decimal x = 0, formul = 0;
public static Decimal pref = -100000, next = 100000,ans;
public static Decimal stepval = next / 10;
public static Decimal prefrem = 1234567890123.1234567890m, nextrem = 1234567890123.1234567890m;
public static Decimal nextremfirst = 0;
public static void Answer()
{
Console.WriteLine("Enter ans");
ans = (Convert.ToDecimal(Console.ReadLine()));
}
public static void Main(string[] args)
{
//Console.WriteLine("Enter ans");
//Answer(Convert.ToDecimal(Console.ReadLine()));
Answer();
//Console.Clear();
while (true)
{
for (var i = 0; i <= go; i++)
{
for (x = pref; x <= next; x += stepval)
{
formul = x;
if (formul < ans)
prefrem = x;
else if (formul > ans)
{
if (nextremfirst == 0)
{
nextrem = x;
nextremfirst += 2;
}
}
else if (formul == ans)
{
AnsFound();
break;
}
else
{
Error();
}
Display();
}
if (formul == ans)
{
AnsFound();
break;
}
if (prefrem != 1234567890123.1234567890m)
pref = prefrem;
if (nextrem != 1234567890123.1234567890m)
next = nextrem;
nextremfirst = 0;
stepval /= 10;
if (formul != ans)
NoAnsyet();
//Console.WriteLine();
}
Finnish();
}
}
public static void Display()
{
//Console.ReadKey();
//Console.WriteLine("Formul: {0} x: {1} Ans: {2} Status: {3}", //formul, x, ans, exception);
//Here is the error:
Console.WriteLine("Pref:{0} Next:{1} Step:{2} Formul:{3} x:{4} Ans:{5} Status:{6}",pref,next,stepval,formul,x,ans,exception);
}
public static void Finnish()
{
if (formul != ans)
Error();
exception = "\ncomplete";
Console.WriteLine(exception);
pref = -100000;
next = 100000;
stepval = next /= 10;
Console.ReadKey();
Console.Clear();
//Console.WriteLine("Enter ans:");
//Answer(Convert.ToDecimal(Console.ReadLine()));
Answer();
}
public static void AnsFound()
{
exception = "\nSolution Found!";
//Console.WriteLine("x: {0} Ans: {1} Status: {2}", x, ans, exception);
//Console.WriteLine("Pref:{0} Next: {1} Stepval: {2} Formul:{3} x:{4} Ans:{5} Status:{}", pref, next, stepval, formul, x, ans, exception);
}
public static void NoAnsyet()
{
exception = "\nNo Solution yet...";
//Console.WriteLine(exception);
}
public static void Error()
{
exception = "\nNo Solution error!!";
Console.WriteLine(exception);
}
}
}
Because you set exception = "\ncomplete"; at different places. The \n at the beginning is a new line character.
Remove the \n
exception = "complete";
Same problem with other texts like "\nSolution Found!".
Using string interpolation makes string formatting more readable:
Replace
Console.WriteLine("Pref:{0} Next:{1} Step:{2} Formul:{3} x:{4} Ans:{5} Status:{6}",
pref, next, stepval, formul, x, ans, exception);
by
Console.WriteLine(
$"Pref:{pref} Next:{next} Step:{stepval} Formul:{formul} x:{x} Ans:{ans} Status:{exception}");
WriteLine writes in a New Line. You should try
Console.Write()
If you want to print right after your previous print.
The value to your variable exception is the reason why the console is printing on a different basically if you put a special character \n means new line hence all the methods you are calling have this special character.
Solution remove special characters and use the Console.WriteLine or Console.Write methods
As per the code provided you have not called the method i made some changes to the code
Edited code
and try to run the code status :No solution found yet
Thanks

ReadLine(); between values

I made a dice game and just a few moments ago asked for a solution here, which i got. it made a new problem and in which i cant seem to find a answer.
Heres the code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Noppapeli
{
class Program
{
static void Main(string[] args)
{
int pyöräytys;
int satunnainen;
int luku = 0;
Random noppa = new Random((int)DateTime.Now.Ticks);
Console.WriteLine("Anna arvaus");
int.TryParse(Console.ReadLine(),out pyöräytys);
Console.WriteLine("Haettava numero on: " + pyöräytys);
Console.ReadLine();
do
{
luku++;
satunnainen = noppa.Next(1, 7);
Console.WriteLine("numero on: " + satunnainen);
if (satunnainen == pyöräytys)
{
satunnainen = pyöräytys;
}
} while (pyöräytys != satunnainen);
Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
Console.WriteLine("Haettu numero: " + pyöräytys);
Console.WriteLine("Pyöräytetty numero: " + satunnainen);
Console.Write("Kesti " + luku + " Nopan pyöräytystä saada tulos!");
Console.ReadLine();
}
}
}
The problem is that int.TryParse(Console.ReadLine(),out pyöräytys); needs to only take values between 1-6. now if I put a 7 in there the game is on a loop to find a 7 from a D6.
Is there a easy solution or should i just make the dices bigger.
You simply need to add some kind of loop to ensure the value is valid and continue looping until a valid value is provided.
pyöräytys = -1; // Set to invalid to trigger loop
while (pyöräytys < 1 || pyöräytys > 6)
{
Console.WriteLine("Anna arvaus");
int.TryParse(Console.ReadLine(),out pyöräytys);
if (pyöräytys < 1 || pyöräytys > 6)
{
Console.WriteLine("Invalid value, must be 1-6"); // Error message
}
}
Just verify the input value is between 1 and 6:
bool valid;
while (!valid)
{
Console.WriteLine("Anna arvaus");
int.TryParse(Console.ReadLine(),out pyöräytys);
valid = (pyöräytys > 0 && pyöräytys <= 6);
}

Categories