keep getting exception, value not getting input into array - c#

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

Related

How to create a class in a loop with custom names in C#

So my program lets me send requests using WSDL the class below is provided by the WSDL:
CreateCustomerNoteRequest createCustomerNotesRequestInfo = new CreateCustomerNoteRequest();
Using this class I have to set the variables like this:
//FIRST WRITING NOTE TO OLD ACCOUNT TO SAY ITS BEEN COMPRIMISED AND SHOW NEW CUSTOMER NUMBER:
createCustomerNotesRequestInfo.UserName = username;
createCustomerNotesRequestInfo.Password = password;
createCustomerNotesRequestInfo.SystemToken = "sysToken";
createCustomerNotesRequestInfo.Note = new CustomerNote();
createCustomerNotesRequestInfo.Note.CustomerNumber = cloneCustomerNumber;
createCustomerNotesRequestInfo.Note.Category = new CustomerServiceWSDL.LookupItem();
createCustomerNotesRequestInfo.Note.Category.Code = "GEN";
createCustomerNotesRequestInfo.Note.Details = "Account Takeover – Fraud. Acc – " + customerNumberTextBox.Text + " closed as compromised and new account " + newCloneCustomerNumber + " created matching existing data";
And to finish off I use this to get my response:
createCustomerNotesResponse = soapClient.CreateCustomerNote(createCustomerNotesRequestInfo);
Everything works fine. What I want to do now is because I have multiple Notes I want to loop this process so depending on how many Note there are it would create that many instances.
I do successfully get all the Notes into a list like this using notecount which provides how many number of notes there are (Given by WSDL) so all is good so far:
try
{
for (int i = 0; i <= notesCount; i++)
{
customerNotesArrayList.Add(getCustomerNotesResponse.Notes.Items[i]);
//i++;
}
}
What I want to do: Now depending on the notes count I want to create that many of this:
CreateCustomerNoteRequest createCustomerNotesRequestInfo = new CreateCustomerNoteRequest();
I tried this:
for (int i=0; i<=notesCount;i++)
{
CreateCustomerNoteRequest a[i] = new CreateCustomerNoteRequest();
}
But its not as easy as that so how can I loop to make this happen?
So I want a1, a2, a3 where Ill then loop all the notes in later which shouldn't be a problem. But creating these in the first place is the problem.
[EDIT]
//Create Notes and copy over array contents...
CreateCustomerNoteRequest request = new CreateCustomerNoteRequest();
for (int i = 0; i <= notesCount; i++)
{
request.UserName = username;
request.Password = password;
request.SystemToken = systemToken;
request.Note = new CustomerNote();
request.Note.CustomerNumber = newCloneCustomerNumber;
request.Note.Category = new CustomerServiceWSDL.LookupItem();
request.Note.Category.Code = customerNotesArrayList[i].NoteCategory.Code.ToString();
request.Note.Details = customerNotesArrayList[i].NoteText;
var response = soapClient.CreateCustomerNote(request);
}
You're declaring the array inside the loop, which means it won't be available afterwards. Furthermore you need to declare the array size beforehand:
CreateCustomerNoteRequest[] a = new CreateCustomerNoteRequest[notesCount];
for (int i = 0; i < notesCount; i++)
{
a[i] = new CreateCustomerNoteRequest();
}
// now you can use the array outside the loop as well
Instead of an array you could choose to use a List<CreateCustomerNoteRequest>, which doesn't need a size declaration first.
Note that if you're planning to get the notes inside the same loop, you won't need the array at all:
for (int i = 0; i < notesCount; i++)
{
CreateCustomerNoteRequest request = new CreateCustomerNoteRequest();
var response = soapClient.CreateCustomerNote(request);
// todo process response
}

c# how to store values from a file in an array [duplicate]

This question already has answers here:
C# parsing a text file and storing the values in an array
(3 answers)
Closed 5 years ago.
I am trying to store values in an array from reading from a file. I have the reading from a file part but I can't get it to store in an array because it gives me an error "Value cannot be null" because after the loop the value of my variable becomes null and the array cannot be null. Here's what I have. And I realize that the for loop probably isn't in the correct spot so any help with where to put it would be great.
Program p = new Program();
int MAX = 50;
int[] grades = new int[MAX];
string environment = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal) + "\\";
string path = environment + "grades.txt";
StreamReader myFile = new StreamReader(path);
string input;
int count = 0;
do
{
input = myFile.ReadLine();
if (input != null)
{
WriteLine(input);
count++;
}
} while (input != null);
for (int i = 0; i < count; i++)
{
grades[i] = int.Parse(input);
}
You start the for loop just after exiting from the while loop. And the condition to exit from the while loop is true when input is null. Of course this is not well accepted by Int.Parse.
Instead you can use a single loop, taking in consideration that you don't want to loop more than 50 times otherwise you exceed the array dimensions
int count = 0;
while((input = myFile.ReadLine()) != null && count < 50)
{
WriteLine(input);
grades[count] = int.Parse(input);
count++;
}
However you can have a more flexible way to handle your input if you use a List<int> instead of an array of integers. In this way you don't have to check for the number of lines present in your file
List<int> grades = new List<int>();
while((input = myFile.ReadLine()) != null)
grades.Add(int.Parse(input));
if we want to get really condensed
var grades = File.ReadAllLines(path).Select(l=>Int.Parse(l)).ToArray();
Utilize the Path.Combine() to help you in concatenating paths.
string environment = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
String fullPath = Path.Combine(environment, "grades.txt");
int[] grades = File.ReadAllLines(fullPath).Select(p => int.Parse(p)).ToArray<int>();
Console.WriteLine(grades);
Refer to https://www.dotnetperls.com/file-readalllines on how to use File.ReadAllLines() its very handy.
I'm using LINQ here, which sometimes simplifies things. Even though it looks a bit intimidating now. We read all lines, the result of that is then parsed by selecting each one and converting it to an integer then outputting an array of integers and saving that to grades.
Program p = new Program();
int MAX = 50;
int[] grades = new int[MAX];
string environment = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal) + "\\";
string path = environment + "grades.txt";
using (StreamReader myFile = new StreamReader(path))
{
string input;
int count = 0;
while((!myFile.EndOfStream) && (count < MAX))
{
input = myFile.ReadLine();
if (!String.IsNullOrWhiteSpace(input))
{
WriteLine(input);
grades[count] = int.Parse(input);
count++;
}
}
}
You should definitely use the "using" pattern around your stream object. Got rid of the for-loop for you while maintaining mostly your code and style. Your issue was that you weren't using the input value before moving on to the next line. You only ever had the last value in your original code.

unable to convert string to int when using streamreader

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();
}

C# Split not working

I'm trying to read data from a file, split the data and save to array. The code works fine except for the split. It is returning a NullException.
Any help would be greatly appreciated.
public static void LoadHandData(CurrentHand[] handData, string fileName)
{
string input = ""; //temporary variable to hold one line of data
string[] cardData; //temporary array to hold data split from input
StreamReader readHand = new StreamReader(fileName);
for (int counter = 0; counter < handData.Length; counter++)
{
input = readHand.ReadLine(); //one record
cardData = input.Split(' '); //split record into fields
int index = 0;
handData[counter].cardSuit = Convert.ToChar(cardData[index++]);
handData[counter].cardValue = Convert.ToInt16(cardData[index++]);
}
readHand.Close();
}
As per the comments, you've only got one line of data. But look at your loop:
for (int counter = 0; counter < handData.Length; counter++)
{
input = readHand.ReadLine(); //one record
cardData = input.Split(' '); //split record into fields
int index = 0;
handData[counter].cardSuit = Convert.ToChar(cardData[index++]);
handData[counter].cardValue = Convert.ToInt16(cardData[index++]);
}
That's trying to read one line per hand. On the second iteration, ReadLine will return null, so when you call input.Split() you'll end up with the NullReferenceException you're seeing.
You need to read the line once and split it. Given that you've only got one line of text, you can just use File.ReadAllText to simplify things:
string input = File.ReadAllText(fileName);
string[] cardData = input.Split(' ');
for (int counter = 0; counter < handData.Length; counter++)
{
handData[counter].cardSuit = Convert.ToChar(cardData[counter * 2]);
handData[counter].cardValue = Convert.ToInt16(cardData[counter * 2 + 1]);
}

Object reference not set to an instance of an object - webservices

I have this error appearing in my web service and even though I'v had a look at the articles on the null issue, I am not able to find how to fix this error
this is my code:
SendInvUpdate.InvServices.UpdateRatePackagesRequest urq = new SendInvUpdate.InvServices.UpdateRatePackagesRequest();
SendInvUpdate.InvServices.UpdateRatePackagesOperationResponse ors = new SendInvUpdate.InvServices.UpdateRatePackagesOperationResponse();
protected void Page_Load(object sender, EventArgs e)
{
Int64 HID = 819942;
Int64 HRID = 154482;
SendInvUpdate.InvServices.UpdateRatePackagesRequest request = new SendInvUpdate.InvServices.UpdateRatePackagesRequest();
ChannelManagerAccount account = new ChannelManagerAccount();
request.HotelId = HID;
int avail = 4;
DateTime frodte = Convert.ToDateTime("2012-04-12");
DateTime todte = Convert.ToDateTime("2012-04-30");
int NoofRatePackages = 3;
UpdateRatePackageRequest[] RatePackages = new UpdateRatePackageRequest[NoofRatePackages];
string res;
request.RatePackages = new UpdateRatePackageRequest[NoofRatePackages];
request.RatePackages = RatePackages;
UpdateRatePackageRequest rp = new UpdateRatePackageRequest();
for (int i = 0; i < NoofRatePackages; i++)
{
rp.RatePackageId = HRID;
RateDetails[] Rates = new RateDetails[NoofRatePackages];
rp.Rates = new RateDetails[NoofRatePackages];
rp.Rates = Rates;
RateDetails rd = new RateDetails();
for (int j = 0; j < NoofRatePackages; j++)
{
rd.Availability = avail;
rd.AvailabilityApplicationType = SendInvUpdate.InvServices.AvailabilityApplicationType.SET;
rd.FromDate = frodte;
rd.ToDate = todte;
}
}
SendInvUpdate.InvServices.InventoryServiceClient icc = new SendInvUpdate.InvServices.InventoryServiceClient();
// ( *Line where the error appears*)
ors = icc.UpdateRatePackages(request);
res = ors.Results.ToString();
}
I know that it has something to do with the RateDetails array and initialising the value of the RateDetails to that instant of request but I am not sure how or what to do with regards to that. In debug mode when looking at values of rp there are no values for rp.Rates[0],rp.Rates[1],rp.Rates[2] also RatePackages[0],RatePackages[1],RatePackages[2] are also null so I have a strong feeling thats where my problem is but I don't have a clue on how to fix.
Would be grateful for any sort of insight to where I've gone wrong!
Move the initialization of icc service reference inside your page_load code as
SendInvUpdate.InvServices.InventoryServiceClient icc = new SendInvUpdate.InvServices.InventoryServiceClient();
ors = icc.UpdateRatePackages(request); ( Line where the error appears)
I'm not an expert in asp.net but you can't base your code on global vars if you don't save them in some persistent container (search about SESSION, VIEWSTATE)
EDIT:
also something seems wrong here
UpdateRatePackageRequest[] RatePackages = new UpdateRatePackageRequest[NoofRatePackages];
string res;
request.RatePackages = new UpdateRatePackageRequest[NoofRatePackages];
request.RatePackages = RatePackages;
should be only request.RatePackages = new UpdateRatePackageRequest[NoofRatePackages]; ?
EDIT2:
You send to the InventoryServiceClient an object request that contains an array of UpdateRatePackageRequest, but after creation of the array you don't set any instance of UpdateRatePackageRequest. So I suppose the InventoryServiceClient fails when reading the values from the array.
I will try to change your for loop in this way
for (int i = 0; i < NoofRatePackages; i++)
{
UpdateRatePackageRequest rp = new UpdateRatePackageRequest();
request.RatePackages[i] = rp;
....
Same error with RateDetails. You create the array, but don't set any value of your array with an actual instance of RateDetails
for (int j = 0; j < NoofRatePackages; j++)
{
RateDetails rd = new RateDetails();
rp.Rates[j] = rd;
....

Categories