I am initializing static array by a method, then want to use it in non static method and it throws nullpointerException. When I have created small example everything worked. I don't know what is wrong with that. Attaching solution.
http://www.speedyshare.com/QRjW5/Funkcjonalnosc-Kopia-2.zip
Main method is in the class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Funkcjonalnosc
{
class Dzwiek
{
static Dzwiek[] tabRefDzwiekow;// = zaladujDzwieki();//przy uruchomeniu dzwieki referencyjne wczytaja sie raz
double hz;
String dzwiek;
bool first = true;
Dzwiek(double hz) {
this.hz = hz;
dzwiek = dopasujDzwiek(hz);
}
Dzwiek(String dzwiek, double hz) {
this.dzwiek = dzwiek;
this.hz = hz;
}
public static void zaladujDzwieki() {
System.IO.StreamReader sr = System.IO.File.OpenText("dzwieki.txt");
tabRefDzwiekow = new Dzwiek[100];
string s = "";
int i = 0;
string[] splitted;
while ((s = sr.ReadLine()) != null) {
splitted = s.Split('\t');
tabRefDzwiekow[i] = new Dzwiek(splitted[0], Double.Parse(splitted[1]));
Console.WriteLine(tabRefDzwiekow[i].hz);
}
sr.Close();
}
//Znajduje odpowiedni dzwiek w tablicy dzwiekow
String dopasujDzwiek(double hz) {
double obecnaRoznica, poprzedniaRoznica = int.MaxValue;
string dopasowanyDzwiek = "";
for (int i = 0; i < tabRefDzwiekow.Length; i++) {
obecnaRoznica = Math.Abs(hz - tabRefDzwiekow[i].hz);//THROWS EXCEPTION!
if (obecnaRoznica > poprzedniaRoznica)
return tabRefDzwiekow[i - 1].dzwiek;
poprzedniaRoznica = obecnaRoznica;
}
return dopasowanyDzwiek;
}
static void Main(string[] args) {
zaladujDzwieki(); //initilize the static ARRAY tabRefDzwieki
Dzwiek dzwiek = new Dzwiek(440); //uses that array by calling function in //constructor doPasujDzwieki()
Console.Read();
}
}
}
unless I'm mising something, whenever you call
tabRefDzwiekow[i] = new Dzwiek(splitted[0], Double.Parse(splitted[1]));
i will always be zero, and then when you access it later, in your for loop,
obecnaRoznica = Math.Abs(hz - tabRefDzwiekow[i].hz);//THROWS EXCEPTION
you're trying to access an uninitialized Dzwiek object's hz property after the first iteration
Related
I want to extract all decimal/ integer value before a character sequence(am/AM) until an alphabet or a special charecter comes up value
Input Output
PEK\n2545 AMAzerbhaijan 2545
PEK\n2545 AMamorphous 2545
ANGwwquui\3.0 amAm 3.0
Awyu&&#^/Non-Prog//#*(*889/328.19 am -> 328.19
qii2781a/k28U28am 28
PEK\nam2545 AM 2545
Can I know what is the best possible way to do this? Thanks in advance.
Given the examples you showed, I believe this would do the trick:
public string ParseData(string input)
{
StringBuilder numberBuilder = new StringBuilder();
string terminatorChars = "am";
bool isCaseSensitive = false;
int terminatorCharLength = terminatorChars.Length;
for (int i = 0; i < input.Length; i++)
{
if (input.Length - i >= terminatorCharLength)
{
var currentSubstr = input.Substring(i, terminatorCharLength);
if ((currentSubstr == terminatorChars) || (!isCaseSensitive && currentSubstr.ToLowerInvariant() == terminatorChars.ToLowerInvariant()))
if(numberBuilder.Length>0)
return numberBuilder.ToString();
}
if (Char.IsDigit(input[i]) || input[i] == '.')
numberBuilder.Append(input[i]);
else if (Char.IsWhiteSpace(input[i]))
continue;
else
numberBuilder.Clear();
}
return null;
}
The data is fixed width data with name the first 50 character and value the data after column 50. See code below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.txt";
static void Main(string[] args)
{
StreamReader reader = new StreamReader(FILENAME);
string line = "";
List<KeyValuePair<string, decimal>> data = new List<KeyValuePair<string,decimal>>();
int lineNumber = 0;
while((line = reader.ReadLine()) != null)
{
if(++lineNumber > 1)
{
string key = line.Substring(0, 50).Trim();
decimal value = decimal.Parse(line.Substring(50));
data.Add(new KeyValuePair<string,decimal>(key,value));
}
}
}
}
}
In my project that i'm working on I have to match 5 numbers for yahtzee. So all these numbers have to be the same. Now I have thought about how to do this but i'm not sure about what the best and easiest way is. Sure I can write it all out but there has to be a shorter way.
I haven't written the code for the part that checks if yahtzee has been thrown. This is because I only can come up with one way and that is to write it all out.
Here's my code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Opdr3
{
class Program
{
struct YahtzeeGame
{
public int[] dobbelstenen;
public Random rnd;
public void Gooi()
{
for (int i = 0; i < 5; i++)
{
dobbelstenen[i] = Int32.Parse(rnd + "");
}
}
public bool Yahtzee()
{
Here it has to check if all dobbelstenen[int]
are the same
}
}
static void Main(string[] args)
{
// maak YahtzeeGame (struct) aan
YahtzeeGame yahtzeeGame;
// initialiseer struct-members
yahtzeeGame.rnd = new Random();
yahtzeeGame.dobbelstenen = new int[5];
// probeer yahtzee te gooien
int aantalPogingen = 0;
do
{
// gooi alle dobbelstenen
yahtzeeGame.Gooi();
aantalPogingen++;
} while (!yahtzeeGame.Yahtzee());
// vermeld aantal pogingen voor yahtzee
Console.WriteLine("Aantal pogingen nodig: {0}", aantalPogingen);
// wacht op gebruiker
Console.ReadKey();
}
}
}
You'll need a little loop:
public bool Yahtzee()
{
// check if all dobbelstenen[int] are the same
for(int i = 1; i < 5; i++) // start with second dobbelstenen
{
if(dobbelstenen[i] != dobbelstenen[0]) return false;
}
return true;
}
It simply compares second, third, ... against the first.
I have never written an application, so I will post the entirety of the code (80 lines). (I come from a background of putting together scripts.)
My goal is to load, or create a list of "used" ports, choose a number within a range that isn't on the list, and if the amount of tries to reach an unused port reaches 129, to run a windows batch file.
This also would turn the chosen port into a .cmd
(some of this is an amalgamation of sources from SO)
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Diagnostics;
using System.IO;
namespace randomport
{
class Core
{
public const int
minval = 8001,
maxval = 8128;
public static int[] usedPorts = new int[]{};
public static int
chosenPort = 0,
tries = 0,
timeout = 10;
public static bool read = false;
public static void Main()
{
if(!read)
{
Read();
read = true;
}
RandGen();
}
public static void RandGen()
{
Process proc = null;
Random rand = new Random();
if(tries < 129) chosenPort = rand.Next(minval, maxval);
else
{
proc.StartInfo.FileName = #"C:\Users\Administrator\Desktop\TerrariaServer\filebin\sendservfull.bat";
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit
(
(timeout <= 0)
? int.MaxValue : timeout * 100 * 60
);
}
for(int i = 0; i < usedPorts.Length; i++)
{
if(chosenPort != usedPorts[i])
{
Write();
// Application.Exit();
}
else
{
tries += 1;
return;
}
}
}
public static void Read()
{
using (StreamReader sr = new StreamReader(#"C:\Users\Administrator\Desktop\TerrariaServer\filebin\activeports.txt"))
{
string[] values = sr.ReadToEnd().Split(';');
for(int i = 0; i < values.Length; i++)
{
int.TryParse(values[i], out usedPorts[i]);
}
}
}
public static void Write()
{
File.AppendAllText(#"C:\Users\Administrator\Desktop\TerrariaServer\filebin\activeports.txt", "set port="+chosenPort+";");
File.Move(#"C:\Users\Administrator\Desktop\TerrariaServer\filebin\activeports.txt", Path.ChangeExtension(#"C:\Users\Administrator\Desktop\TerrariaServer\filebin\activeports.txt", ".cmd"));
}
}
}
I have a little work to do on the final export (like removing ";").
The script compiles, but does not run as intended. Something is definitely wrong, but I am unaware of it. If it is something obvious, I guess that would be handy, otherwise if it is simply format and so on, I clearly need to do a little more studying.
Compiled using visual studio 2008 express this time, and cleaned it up. It was hard to tell which were the issues without a debugger, such as a missing parenthesis.
File writing, compiling, and crashing solved..
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Diagnostics;
using System.IO;
namespace randomport
{
class Core
{
public static int[] usedPorts = new int[] { };
public static int
minval = 8001,
maxval = 8129,
chosenPort = 0,
timeout = 10,
temp = 1024;
public static bool read = false;
public static void Main(string[] args)
{
string path = System.Environment.GetEnvironmentVariable("USERPROFILE");
if (!Directory.Exists(String.Concat(path, "\\desktop\\TerrariaServer\\filebin\\activeports.txt")))
{
Directory.CreateDirectory(String.Concat(path, "\\desktop\\TerrariaServer\\filebin"));
// using (StreamWriter sw = File.CreateText(String.Concat(path, "\\desktop\\TerrariaServer\\filebin\\activeports.txt"))) { }
}
if (!Directory.Exists(String.Concat(path, "\\desktop\\TerrariaServer\\filebin\\chosenport.cmd")))
{
Directory.CreateDirectory(String.Concat(path, "\\desktop\\TerrariaServer\\filebin"));
using (StreamWriter sw = File.CreateText(String.Concat(path, "\\desktop\\TerrariaServer\\filebin\\chosenport.cmd"))) { }
}
if (args.Length > 0)
{
if (args[0] == "-noread")
{
}
else if (args[0] == "-read" || args[0] == "-default")
{
if (!read)
{
Read();
read = true;
}
}
}
else
{
if (!read)
{
Read();
read = true;
}
}
if (args.Length >= 3)
{
if (args[1] != "-default" || args[1] != "0")
{
int.TryParse(args[1], out temp);
if (temp > 1024 && temp < 65535)
{
minval = temp;
}
}
if (args[2] != "-default" || args[2] != "0")
{
int.TryParse(args[2], out temp);
if (temp > 1024 && temp < 65535)
{
maxval = temp;
}
}
}
RandGen();
}
public static void RandGen()
{
string path = System.Environment.GetEnvironmentVariable("USERPROFILE");
Random rand = new Random();
chosenPort = rand.Next(minval, maxval);
for (int i = 0; i < usedPorts.Length; i++)
{
if (chosenPort != usedPorts[i])
{
Write();
}
else return;
}
}
public static void Read()
{
string path = System.Environment.GetEnvironmentVariable("USERPROFILE");
if (!File.Exists(String.Concat(path, "\\desktop\\TerrariaServer\\filebin\\activeports.txt")))
{
File.Create(String.Concat(path, "\\desktop\\TerrariaServer\\filebin\\activeports.txt"));
}
using (StreamReader sr = new StreamReader(String.Concat(path, "\\desktop\\TerrariaServer\\filebin\\activeports.txt")))
{
string[] values = sr.ReadToEnd().Split(';');
usedPorts = new int[values.Length];//Initialize the array with the same length as values
for (int i = 0; i < values.Length; i++)
{
int.TryParse(values[i], out usedPorts[i]);
}
}
}
public static void Write()
{
string path = System.Environment.GetEnvironmentVariable("USERPROFILE");
File.AppendAllLines(String.Concat(path, "\\desktop\\TerrariaServer\\filebin\\activeports.txt"), new string[] { chosenPort + ";" });
using (StreamWriter sw2 = File.CreateText(String.Concat(path, "\\desktop\\TerrariaServer\\filebin\\chosenport.cmd")))
{
sw2.WriteLine("set port=" + chosenPort);
}
Environment.Exit(0);
}
}
}
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I'm a newbie in programming, especially in c#. I have written some code but I keep getting an error when running it and I can't move on until I get that fixed.
The error in question is a NullReferenceException. It also tells me "Object reference not set to an instance of an object".
It seems like a pretty clear error message indicating that an object hasn't been instantiated yet. However I thought I had done that. I hope someone can explain to me what I'm doing wrong. Here's my code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace EvenHelemaalOvernieuw
{
class Globals
{
public static int size = 50;
public static int factor = 3;
public static int puzzleNumber = 1;
public static Square[,] allSquares = new Square[Globals.factor * Globals.factor, Globals.factor * Globals.factor];
public static String path = #"" + factor.ToString() + "\\" + puzzleNumber.ToString() + ".txt";
public static int[,][,] values = new int[factor, factor][,];
public Globals() { }
public void setSize(int s)
{
size = s;
if (size > 100)
{
size = 100;
}
if (size < 20)
{
size = 20;
}
}
public void setFactor(int f)
{
factor = f;
if (factor > 5)
{
factor = 5;
}
if (factor < 2)
{
factor = 2;
}
}
public Square getSquare(int x, int y)
{
return allSquares[x, y];
}
public static void readPuzzle()
{
List<int> conversion = new List<int>();
int count = 0;
using (StreamReader codeString = new StreamReader(path))
{
String line = codeString.ReadToEnd();
Array characters = line.ToCharArray();
foreach (char a in characters)
{
if (a.ToString() != ",")
{
conversion.Add(Convert.ToInt32(a));
}
}
for (int panelX = 0; panelX < factor; panelX++)
{
for (int panelY = 0; panelY < factor; panelY++)
{
for (int squareX = 0; squareX < factor; squareX++)
{
for (int squareY = 0; squareY < factor; squareY++)
{
values[panelX, panelY][squareX, squareY] = conversion[count];
count++;
}
}
}
}
}
}
}
}
The line that is indicated by the error message is near the bottom and reads values[panelX, panelY][squareX, squareY] = conversion[count];.
The problem is the following line
public static int[,][,] values = new int[factor, factor][,];
This is an array of arrays but this code only creates the outer array. The inner array is uninitialized and will be null. Hence when the following code runs it will throw a NullReferenceException trying to access the inner array
values[panelX, panelY][squareX, squareY] = conversion[count];
To fix this just initialize the array elements right before the 3rd nested loop
values[panelX, panelY] = new int[factor, factor];
for (int squareX = 0; squareX < factor; squareX++)
I am looking for fast class for to work with text files and comfortable reading different object (methods like NextInt32, NextDouble, NextLine, etc). Can you advice me something?
Edit: BinaryReader is bad class in my case. Format of my data is not binary. I have file like
1 2 3
FirstToken NextToken
1.23 2,34
And I want read this file with code like:
int a = FileReader.NextInt32();
int b = FileReader.NextInt32();
int c = FileReader.NextInt32();
int d = FileReader.NextString();
int e = FileReader.NextString();
int f = FileReader.NextDouble();
int g = FileReader.NextDouble();
Edit2: I am looking for analog Scanner from Java
I believe this extension method for TextReader would do the trick:
public static class TextReaderTokenizer
{
// Adjust as needed. -1 is EOF.
private static int[] whitespace = { -1, ' ', '\r' , '\n', '\t' };
public static T ReadToken<T>(this TextReader reader)
{
StringBuilder sb = new StringBuilder();
while (Array.IndexOf(whitespace, reader.Peek()) < 0)
{
sb.Append((char)reader.Read());
}
return (T)Convert.ChangeType(sb.ToString(), typeof(T));
}
}
It can be used thus:
TextReader reader = File.OpenText("foo.txt");
int n = reader.ReadToken<int>();
string s = reader.ReadToken<string>();
[EDIT] As requested in question comments, here's an instance wrapper version of the above that is parametrized with delimiters and CultureInfo:
public class TextTokenizer
{
private TextReader reader;
private Predicate<char> isDelim;
private CultureInfo cultureInfo;
public TextTokenizer(TextReader reader, Predicate<char> isDelim, CultureInfo cultureInfo)
{
this.reader = reader;
this.isDelim = isDelim;
this.cultureInfo = cultureInfo;
}
public TextTokenizer(TextReader reader, char[] delims, CultureInfo cultureInfo)
{
this.reader = reader;
this.isDelim = c => Array.IndexOf(delims, c) >= 0;
this.cultureInfo = cultureInfo;
}
public TextReader BaseReader
{
get { return reader; }
}
public T ReadToken<T>()
{
StringBuilder sb = new StringBuilder();
while (true)
{
int c = reader.Peek();
if (c < 0 || isDelim((char)c))
{
break;
}
sb.Append((char)reader.Read());
}
return (T)Convert.ChangeType(sb.ToString(), typeof(T));
}
}
Sample usage:
TextReader reader = File.OpenText("foo.txt");
TextTokenizer tokenizer = new TextTokenizer(
reader,
new[] { ' ', '\r', '\n', '\t' },
CultureInfo.InvariantCulture);
int n = tokenizer.ReadToken<int>();
string s = tokenizer.ReadToken<string>();
I'm going to add this as a separate answer because it's quite distinct from the answer I already gave. Here's how you could start creating your own Scanner class:
class Scanner : System.IO.StringReader
{
string currentWord;
public Scanner(string source) : base(source)
{
readNextWord();
}
private void ReadNextWord()
{
System.Text.StringBuilder sb = new StringBuilder();
char nextChar;
int next;
do
{
next = this.Read();
if (next < 0)
break;
nextChar = (char)next;
if (char.IsWhiteSpace(nextChar))
break;
sb.Append(nextChar);
} while (true);
while((this.Peek() >= 0) && (char.IsWhiteSpace((char)this.Peek())))
this.Read();
if (sb.Length > 0)
currentWord = sb.ToString();
else
currentWord = null;
}
public bool HasNextInt()
{
if (currentWord == null)
return false;
int dummy;
return int.TryParse(currentWord, out dummy);
}
public int NextInt()
{
try
{
return int.Parse(currentWord);
}
finally
{
readNextWord();
}
}
public bool HasNextDouble()
{
if (currentWord == null)
return false;
double dummy;
return double.TryParse(currentWord, out dummy);
}
public double NextDouble()
{
try
{
return double.Parse(currentWord);
}
finally
{
readNextWord();
}
}
public bool HasNext()
{
return currentWord != null;
}
}
You should define exactly what your file format is meant to look like. How would you represent a string with a space in it? What determines where the line terminators go?
In general you can use TextReader and its ReadLine method, followed by double.TryParse, int.TryParse etc - but you'll need to pin the format down more first.
Have you checked out the BinaryReader class? Yes it's a text file but there is nothing stopping you from treating it as binary data and hence using BinaryReader. It has all of the methods that you are looking for with the exception of ReadLine. However it wouldn't be too difficult to implement that method on top of BinaryReader.
If you do need text files (ie UTF-8 or ASCII encoding) then the binary writer will not work.
You can use the TextReader, but unlike the BinaryReader and the TextWriter it does not support any types other than Line and char. You will have to define what separators are allowed and parse the Line base data yourself.
The System.IO.BinaryReader class is what you need.
Example of implementation of a ReadLine method:
public static class Extensions
{
public static String ReadLine(this BinaryReader binaryReader)
{
var bytes = new List<Byte>();
byte temp;
while ((temp = (byte)binaryReader.Read()) < 10)
bytes.Add(temp);
return Encoding.Default.GetString(bytes.ToArray());
}
}
Example for using this class:
using System;
using System.IO;
using System.Security.Permissions;
class Test
{
static void Main()
{
// Load application settings.
AppSettings appSettings = new AppSettings();
Console.WriteLine("App settings:\nAspect Ratio: {0}, " +
"Lookup directory: {1},\nAuto save time: {2} minutes, " +
"Show status bar: {3}\n",
new Object[4]{appSettings.AspectRatio.ToString(),
appSettings.LookupDir, appSettings.AutoSaveTime.ToString(),
appSettings.ShowStatusBar.ToString()});
// Change the settings.
appSettings.AspectRatio = 1.250F;
appSettings.LookupDir = #"C:\Temp";
appSettings.AutoSaveTime = 10;
appSettings.ShowStatusBar = true;
// Save the new settings.
appSettings.Close();
}
}
// Store and retrieve application settings.
class AppSettings
{
const string fileName = "AppSettings####.dat";
float aspectRatio;
string lookupDir;
int autoSaveTime;
bool showStatusBar;
public float AspectRatio
{
get{ return aspectRatio; }
set{ aspectRatio = value; }
}
public string LookupDir
{
get{ return lookupDir; }
set{ lookupDir = value; }
}
public int AutoSaveTime
{
get{ return autoSaveTime; }
set{ autoSaveTime = value; }
}
public bool ShowStatusBar
{
get{ return showStatusBar; }
set{ showStatusBar = value; }
}
public AppSettings()
{
// Create default application settings.
aspectRatio = 1.3333F;
lookupDir = #"C:\AppDirectory";
autoSaveTime = 30;
showStatusBar = false;
if(File.Exists(fileName))
{
BinaryReader binReader =
new BinaryReader(File.Open(fileName, FileMode.Open));
try
{
// If the file is not empty,
// read the application settings.
// First read 4 bytes into a buffer to
// determine if the file is empty.
byte[] testArray = new byte[3];
int count = binReader.Read(testArray, 0, 3);
if (count != 0)
{
// Reset the position in the stream to zero.
binReader.BaseStream.Seek(0, SeekOrigin.Begin);
aspectRatio = binReader.ReadSingle();
lookupDir = binReader.ReadString();
autoSaveTime = binReader.ReadInt32();
showStatusBar = binReader.ReadBoolean();
}
}
// If the end of the stream is reached before reading
// the four data values, ignore the error and use the
// default settings for the remaining values.
catch(EndOfStreamException e)
{
Console.WriteLine("{0} caught and ignored. " +
"Using default values.", e.GetType().Name);
}
finally
{
binReader.Close();
}
}
}
// Create a file and store the application settings.
public void Close()
{
using(BinaryWriter binWriter =
new BinaryWriter(File.Open(fileName, FileMode.Create)))
{
binWriter.Write(aspectRatio);
binWriter.Write(lookupDir);
binWriter.Write(autoSaveTime);
binWriter.Write(showStatusBar);
}
}
}
You can probably use the System.IO.File Class to read the file and System.Convert to parse the strings you read from the file.
string line = String.Empty;
while( (line = file.ReadLine()).IsNullOrEmpty() == false )
{
TYPE value = Convert.ToTYPE( line );
}
Where TYPE is whatever type you're dealing with at that particular line / file.
If there are multiple values on one line you could do a split and read the individual values e.g.
string[] parts = line.Split(' ');
if( parts.Length > 1 )
{
foreach( string item in parts )
{
TYPE value = Convert.ToTYPE( item );
}
}
else
{
// Use the code from before
}