I am having trouble converting a string to an int. Ive looked around and have been told to use the int.Parse but it isn't helping.
I have created an object Winner that has a int WinnerScore and string WinnerName.
I am trying to add these values to an array Winner[] before sorting them.
When I run this code it says:
NullReferenceException was unhandled
Object reference not set to an instance of an object.
Any idea why this is happening?
StreamReader sr = new StreamReader("highscores.txt");
for (int u = 0; u < nWinners; u++)
{
unsortedList[u].WinnerScore = int.Parse(sr.ReadLine());
unsortedList[u].WinnerName = sr.ReadLine();
}
sr.Close();
With a certain confidence I can suppose that you have declared the array unsortedList but you haven't initialized the objects of Winner class that you want to store in that array.
Simply declaring
Winner[] unsortedList = new Winner[100];
creates an array that could store 100 instances of Winner but this array is empty, there are no instances of a Winner class in the 100 slots available, they are all null. You should create every single Winner instances that you want to store in the 100 slots of the array.
So, as an example, your code could be rewritten as
Winner[] unsortedList = new Winner[nWinners];
using(StreamReader sr = new StreamReader("highscores.txt"))
{
for (int u = 0; u < nWinners; u++)
{
Winner w = new Winner();
w.WinnerScore = int.Parse(sr.ReadLine());
w.WinnerName = sr.ReadLine();
unsortedList[u] = w;
}
sr.Close();
}
However, this has the drawback that you need to know, before entering the loop, the exact number of Winner objects required to dimension your array, If, for some reason, you fail to count them correctly, you fall in another problem (Index Out Of Range).
In this case it is always better to use a List<Winner> where you don't need to know before hand the exact number of elements
List<Winner> unsortedList = new List<Winner>();
using(StreamReader sr = new StreamReader("highscores.txt"))
{
while((line = sr.ReadLine()) != null))
{
Winner w = new Winner();
w.WinnerScore = int.Parse(line);
w.WinnerName = sr.ReadLine();
unsortedList.Add(w);
}
sr.Close();
}
You've left creation as well as initialization:
// My suggestion of unsortedList generic type
public struct Winner {
public int WinnerScore;
public String WinnerName;
}
...
// 1. You shoud create unsortedList:
List<Winner> unsortedList = new List<Winner>();
// 2. You should also initialize the list with Winner instances
for (int u = 0; u < nWinners; ++u)
unsortedList.Add(new Winner());
// 3. Only that you can fill unsortedList from file.
// And you original code becames the correct one
using (StreamReader sr = new StreamReader("highscores.txt")) {
for (int u = 0; u < nWinners; ++u) {
unsortedList[u].WinnerScore = int.Parse(sr.ReadLine());
unsortedList[u].WinnerName = sr.ReadLine();
}
}
var unsortedList = new List<Winner>();
var nWinners = 100;
using (StreamReader sr = new StreamReader("highscores.txt"))
{
for (int i = 0; i < nWinners; i++)
{
var winer = new Winner();
winer.WinnerScore = int.Parse(sr.ReadLine());
winer.WinnerName = sr.ReadLine();
unsortedList.Add(winer);
}
sr.Close();
}
Related
I have a piece of code that is supposed to streamread this text file:
1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
1.1.1.2.2.2.2.1.1.1.2.2.1.1.1
1.2.2.2.2.2.2.2.2.2.2.2.2.1.1
1.1.2.2.2.2.2.2.2.2.2.2.2.1.1
1.1.2.2.2.2.2.2.2.2.2.2.1.1.1
1.1.1.1.2.2.2.2.2.2.2.2.1.1.1
1.1.1.1.2.2.2.2.2.2.1.1.1.1.1
1.1.1.1.1.1.2.2.2.1.1.1.1.1.1
1.1.1.1.1.1.1.2.1.1.1.1.1.1.1
1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
1.1.1.1.1.1.1.1.1.1.2.2.1.1.1
1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
Everything is going fine, kinda of. My purpose was to rummage through all the characters one by one, then after that's done start on a new line. This is where my little problem occurs, which I've been trying to fix all night.
It reads the first line nicely, but then it doesn't read the second line...
Here is the code:
System.IO.StreamReader file = new System.IO.StreamReader(#"C:\Text\TextFile.txt");
int loadX = 0;
int loadY = 0;
string line;
while (true)
{
if (loadX <= 12)
{
loadX++;
while ((line = file.ReadLine()) != null)
{
System.Threading.Thread.Sleep(500);
string[] entries = line.Split('.');
System.Console.Write(entries[loadX]);
loadY++;
}
}
System.Threading.Thread.Sleep(500);
Console.Write($" Finished {loadX}");
loadX = 0;
}
var lines = File.ReadAllLines(#"C:\Text\TextFile.txt");
var points = lines.SelectMany((l, x) => l.Split('.').Select((s, y) => new {X = x, Y = y, Value = s}));
foreach (var point in points)
{
Console.WriteLine($"({point.X}, {point.Y})={point.Value}");
}
Using a while loop and StremReader seems so silly when you have easier and more readable ways of handling this.
You can easily simplify your code by doing File.ReadAllLines()
//lines will be a string array
var lines = File.ReadAllLines(#"C:\Text\TextFile.txt");
for(int x = 0; x < lines .Length; x++)
{
var cols = lines [x].Split('.');
for(int y = 0; y < cols.Length; x++)
{
//Here you have access to the value, and the x and y position
Console.WriteLine("x: {0}, y: {1} value: {2}", x, y, cols[y]);
}
}
Demo here
If you want to go through every number in this file with X and Y then this is an example how you can do so:
string[] lines = File.ReadAllLines(#"C:\Text\TextFile.txt");
for(int indexY = 0; indexY < lines.Length; indexY++){
string[] lineEntries = lines[indexY].Split('.');
for(int indexX = 0; indexX < lineEntries; indexX++){
// here you have one number by accessing
// it with lineEntries[indexX]
Console.Write(lineEntries[indexX]);
}
Console.WriteLine();
}
You are mistaken to think it is reading the first line. In fact, your current code reads the first value of each line. Due to your input this just happens to be a similar output to what the first line would be, which has lead to your confusion.
Your main loop should be looping through each line, then you can process the line and loop through each value. Which you can then use however you want.
Here is an example:
using(System.IO.StreamReader file = new System.IO.StreamReader(#"C:\Text\TextFile.txt"))
{
int loadX = 0;
int loadY = 0;
string line;
// Loop through each line as you read it.
while ((line = file.ReadLine()) != null)
{
// Split the line to get an array of values.
string[] entries = line.Split('.');
// Loop through each value and process.
for(int i = 0; i < entries.length; i++)
{
string entry = entries[i];
// TODO: Do something with entry.
loadY++;
}
loadX++;
}
}
Obviously in this example loadX and loadY are not being used, but this demonstrates how to correctly increment them so you can use them as needed.
TIP: When using a SteamReader you should ensure you dispose of it correctly, this is best done by including it in a using block.
Here is my code.. I'm trying to read in from a file with comma delimited data and the names are in the file as "Doe,John" so I am using this to get the name, without it being seperated out by the comma....
fileIn = new TextFieldParser(INPUT_FILE_NAME);
fileIn.TextFieldType = FieldType.Delimited;
fileIn.SetDelimiters(",");
fileIn.HasFieldsEnclosedInQuotes = true;
Here is some of my source code. The name is not being put into nameArray[i] = words[1];
static void InputEmployeeData()
{
int i;
string[] words;
numOfEmployee = Int32.Parse(fileIn.ReadLine());
idArray = new int[numOfEmployee];
nameArray = new string[numOfEmployee];
deptArray = new int[numOfEmployee];
payrateArray = new double[numOfEmployee];
hoursArray = new double[numOfEmployee];
for (i = 0; i <= numOfEmployee; i++)
{
words = fileIn.ReadFields();
idArray[i] = Int32.Parse(words[0]);
nameArray[i] = words[1];
deptArray[i] = Int32.Parse(words[2]);
payrateArray[i] = Double.Parse(words[3]);
hoursArray[i] = Double.Parse(words[4]);
}
}
A sample line from the data file I am reading in from is this.
0090,"Baker, John",1,32.57,50.75
I have numOfEmployee = readline because there is metadata at the top of the file to let me know how many persons are in the file. I keep getting an exception (Object reference not set to an instance of an object) on line 86....
idArray[i] = int.Parse(words[0]);
You need to change this line
for (i = 0; i <= numOfEmployee; i++)
to
for (i = 0; i < numOfEmployee; i++)
The for loop cycles to many times because it start from zero so, you should stop at numOfEmployee - 1. If you execute the loop as is, in the last loop the words array is set to null by the TextFieldParser.ReadFields and you get the Object Reference Not Set Exception
So i have to write a program that reads values (numbers) from Values.txt file and store them into array of integers (at the beginning i dont know the number of values in file so i dont know the length of array).
First i loop through the file and use counter variable to get the number of values to store into array. Then comes the problem, i dont know how to start from the beginning of file to catch values and store them into array.
When i run it i get 0 0 0 0 0 as a result.
If instead of
myReader.DiscardBufferedData();
myReader.BaseStream.Seek(0, SeekOrigin.Begin);
myReader.BaseStream.Position = 0;
I use the myReader.Close() and then myReader = new StreamReader("Values.txt), the result is correct, can somebody please explain why this is happening and howcan i fix this code :)
string lineOfText = "";
int counter = 0;
int[] intArray;
StreamReader myReader = new StreamReader("Values.txt");
while(lineOfText != null)
{
lineOfText = myReader.ReadLine();
if(lineOfText != null)
{
counter++;
}
}
intArray = new int[counter];
myReader.DiscardBufferedData();
myReader.BaseStream.Seek(0, SeekOrigin.Begin);
myReader.BaseStream.Position = 0;
counter = 0;
while(lineOfText != null)
{
lineOfText = myReader.ReadLine();
if (lineOfText != null)
{
intArray[counter] = int.Parse(lineOfText);
}
counter++;
}
myReader.Close();
for (int j = 0; j < intArray.Length; j++)
{
Console.WriteLine(intArray[j]);
}
This explains how to reset the stream if you want to do it in one pass Return StreamReader to Beginning.
Are you required to use an array? A list would be perfect for what your doing, you can then later push that list into an array or just work directly from the list. Code example below:
List<string> ints = new List<string>();
using (StreamReader sr = new StreamReader("example.txt"))
{
ints.Add(sr.ReadLine());
}
I want to read files from an external datafile, stick them into an array to import to Unity3D.
So I started this:
int [,] positionTab = new int[noLoc,3];
StreamReader sr = new StreamReader(myTextFile);
while((line = sr.ReadLine()) != null)//read line by line up to the end
{
if (line.Contains("confTrain1"))
{
locationTrain1 = RetrieveValueInDataFile.locationTrain(line);
}
else if (line.Contains("confTrain2"))
{
locationTrain2 = RetrieveValueInDataFile.locationTrain(line);
}
else
{
distanceBetweenThem =RetrieveValueInDataFile.distBetweenTrain(line);
}
I wonder to have something like :
int [,] locations = new int [noLoc, 3]
{
{locationTrain1, locationTrain2, distanceBetweenThem}
{locationTrain1, locationTrain2, distanceBetweenThem}
{etc}
}
The problem is I have no idea how to do this in the StreamReader. I mean, how can I add the two locations and the distance (the syntax)?
You can only use such array initialization syntax when constructing array.
If you need to set values of an existing array (as in your sample) - use indexing:
int [,] locations = new int [noLoc, 3]
var rowIndex = 0;
using(StreamReader sr = new StreamReader(myTextFile))
{
while(
rowIndex < noLoc && // if using array you have to read no more than allocated
(line = sr.ReadLine()) != null)
{
locations[rowIndex,0] = locationTrain1;
locations[rowIndex,1] = locationTrain2;
locations[rowIndex,2] = distanceBetweenThem;
rowIndex++;
}
}
Note that it would likely be better to define class that holds this values and store them in a List as you read them.
I have a file contains two lines . and in which line there is a double parameter .
I want to read both lines from the file and save them in an array of doubles .
I used the C# code below , but It doesn't work . It doesn't read anything and the array is empty after running the code .
Anybody has any idea where did I do wrong ?
Thanks for help .
private FileStream input;
double[] arr;
int i = 1;
input = new FileStream(Application.StartupPath+"\\City.txt", FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(input);
while (!reader.EndOfStream)
{
arr[i] = Convert.ToDouble(reader.ReadLine());
i++;
}
reader.Close();
This is a complete example of what you are doing.
string line;
List<double> values = new List<double>();
string path = Path.Combine(Application.StartupPath, "City.txt");
System.IO.StreamReader file = new System.IO.StreamReader(path);
while((line = file.ReadLine()) != null)
{
values.Add(double.Parse(line));
}
file.Close();
Based on "How to: Read a Text File One Line At a Time (MSDN)"
try this approach
using (StreamReader sr = File.OpenText(Application.StartupPath+"\\City.txt"))
{
string line;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
{
arr[i] = Convert.ToDouble(line);
i++;
}
}
and you should at least initialize arr: arr = new double[_size] and i should be zero because arrays in c# are zero based. And better use generic collection like List<T>(List<double> in this case).
The issue is while (!reader.EndOfStream) because when you initially read it in the position is at the end of the file. This is solidified by the fact that the line arr[i] should fail because you've not initialized the array (in fact, it shouldn't even compile...). So, how about this:
double[] arr = new double[2];
...
reader.BaseStream.Position = 0;
while (!reader.EndOfStream)
{
arr[i] = Convert.ToDouble(reader.ReadLine());
i++;
}
However, a more straight forward approach would be something like this:
var arr = new List<double>();
var lines = File.ReadAllLines(Application.StartupPath+"\\City.txt");
foreach (var l in lines)
{
arr.Add(Convert.ToDouble(l));
}
return arr.ToArray();
Another option is use File.ReadAllLines, considering that file size is small.
string[] stringDoubles = File.ReadAllLines(path, Encoding.UTF8);
for(int i=0;i<stringDoubles.Length;i++)
arr[i] = Convert.ToDouble(stringDoubles[i]);
The code as you posted will not compile, because you have not initialized your array, as well as having a visibility modifier on your FileStream. I'd guess this code is from two different locations in your project.
However, there's a much simpler way to do this: File.ReadAllLines
string path = #"c:\dev\text.txt"; //your path here
string[] lines = File.ReadAllLines(path);
double[] doubles = new double[2];
for (int i = 0; i < doubles.Length; i++)
{
double d;
if (double.TryParse(lines[i], out d))
doubles[i] = d;
}