Putting a Struct in a Dictionary [duplicate] - c#

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 5 years ago.
i want to use a struct in a dictionary its key is a string and the value is the struct. i don't know what's the syntax as i'm new to c# i was writing c++ before.
BTW i want to read from a text file and put the lines in the dictionary.
here's what i did already:
public class CDinfo
{
public string code;
public string type;
public int count;
}
private void button1_Click(object sender, EventArgs e)
{
string pathsource = #"F:\Computer Science\CD & Instruments\CDs.txt";
CDinfo lolo = new CDinfo();
string name;
name = textBox1.Text;
lolo.type = textBox2.Text;
lolo.code = textBox3.Text;
lolo.count = int.Parse(count.Text);
Dictionary<string, CDinfo> MS = new Dictionary<string, CDinfo>();
StreamReader reader = new StreamReader(pathsource);
while (reader.Peek() != -1)
{
string m;
string[] fasl;
m = reader.ReadLine();
fasl = m.Split(',');
lolo.type = fasl[1];
lolo.code = fasl[2];
lolo.count = fasl[3];
MS.Add(fasl[0], lolo);
}
reader.Close();
StreamWriter sw = new StreamWriter(pathsource, append: true);
string s = name + ',' + lolo.type + ',' + lolo.code + ',' + lolo.count;
sw.WriteLine(s);
sw.Close();
MessageBox.Show("CD Added Successfully.");
textBox1.Clear();
textBox2.Clear();
textBox3.Clear();
}
After running the solution i'm getting this error "Index was outside the bounds of the array".

You are initializing a new dictionary every time you click Button1, and you are not keeping track of it, so you will never be able to use it from a different context. You need to defined your dictionary as a class variable, and add a value to it from inside your click method:
Dictionary<string, CDinfo> MS = new Dictionary<string, CDinfo>(); // initialize the dictionary somewhere outside of your click handler
private void button1_Click(object sender, EventArgs e)
{
CDinfo lolo = new CDinfo();
string name;
name = textBox1.Text;
lolo.type = textBox2.Text;
lolo.code = textBox3.Text;
lolo.count = int.Parse(count.Text);
// add to the dictionary here
MS.Add(name, lolo);
}
Also, as some of the comments have already mentioned, CDinfo should probably be a class, not a struct.

Related

Exception guidance [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Throwing an exception on this line:
AnnuityReader.WriteLine(fields[0] + "," + fields[1] + "," + fields[3] + "," + fields[4]);
I know there are some similar posts out here which have been resolved, but I have not figured it out yet. Any input is appreciated.
InitializeComponent();
}
StreamWriter AnnuityReader;
List<string[]> Accounts = new List<string[]>();
private int x;
private void Assignment2_Load(object sender, EventArgs e)
{
string currentLine;
string[] fields = new string[2];
//Create streamreader
StreamReader AnnuityReader = new StreamReader("annuities.txt");
while (AnnuityReader.EndOfStream == false)
{
currentLine = AnnuityReader.ReadLine();
fields = currentLine.Split(',');
Accounts.Add(fields);
cmbAccount.Items.Add(fields[0]);
}
AnnuityReader.Close(); //Creates dictionary
}
private void cmbAccount_SelectedIndexChanged(object sender, EventArgs e)
{
lstAccountDetails.Items.Clear();
int index = cmbAccount.SelectedIndex;
string[] fields;
fields = Accounts[index];
lstAccountDetails.Items.Add(String.Format("{0,10} {1,10}{2,10}", "Rate", "Deposit($)", "Value($)"));
lstAccountDetails.Items.Add(String.Format("{0,10} {1,10:C}{2,10:C}", fields[1], double.Parse(fields[2]), double.Parse(fields[4])));
}
private void btnProcess_Click(object sender, EventArgs e)
{
lstAccountDetails.Items.Clear();
double deposit;
int index = cmbAccount.SelectedIndex;
string[] fields = Accounts[index];
try
{
deposit = double.Parse(txtDeposit.Text);
}
catch
{
MessageBox.Show("Enter a positive number");
txtDeposit.SelectAll();
txtDeposit.Focus();
return;
}
double currentValue = double.Parse(fields[4]);
if (deposit > 0)
{
currentValue += deposit;
}
else
MessageBox.Show("Please enter a positive number");
fields[4] = currentValue.ToString();
fields = Accounts[x];
AnnuityReader.WriteLine(fields[0] + "," + fields[1] + "," + fields[3] + "," + fields[4]);
lstAccountDetails.Items.Add(String.Format("{0,10} {1,10}{2,10}", "Rate", "Deposit($)", "Value($)"));
lstAccountDetails.Items.Add(String.Format("{0,10} {1,10:C}{2,10:C}", fields[1], double.Parse(fields[2]), double.Parse(fields[4])));
txtDeposit.Clear();
AnnuityReader.Close();
}
Error is pretty clear. Object reference not set to an instance of an object. You are defining StreamWriter AnnuityReader but you are using that reference without setting to an object in btnProcess_Click function.
You can solve it in two ways. You need to set it to an instance in constructor or in your btnProcess_Click function before using. You can set it to an object like you did in Assignment2_Load function.
StreamReader AnnuityReader = new StreamReader("annuities.txt");

C# how to get proper string from GetString()

I use:
propItem.Value = System.Text.Encoding.UTF8.GetBytes(textBox1.Text + "\0");
where textBox1.Text contains "MMM", to set the Value and save it in a file (propItem.Value is byte[]), but when I try to read the file I use:
string myString = System.Text.Encoding.UTF8.GetString(propItem.Value);
and get: "M\0M\0M\0\0\0". Could anybody advice how to get the proper string, without '\0'. I have seen all the answers here regarding the similar problems, but none of the answers worked in my case.
Loading the file:
Image img0 = null;
string sourceFile;
private void btnLoad_Click(object sender, EventArgs e)
{
using (var selectFileDialog = new OpenFileDialog())
{
if (selectFileDialog.ShowDialog() == DialogResult.OK)
{
sourceFile = selectFileDialog.FileName;
img0 = Image.FromFile(sourceFile);
PropertyItem[] propItems = img0.PropertyItems;
textBox1.Text = "Nothing in the file.";
foreach (PropertyItem propItem in propItems)
{
if (propItem.Id == 0x9286)
{
string myString = System.Text.Encoding.UTF8.GetString(propItem.Value);
textBox1.Text = myString ;
}
}
}
}
}
It should be:
string myString = System.Text.Encoding.Unicode.GetString(propItem.Value);

How to read a text file's data vertically or column wise

How can we read a text file column by column.
Check my new code: I can read the data row-wise using text.split (' ')
But how can be the file read as column wise? Lets assume that a file contains number of rows and columns but I was able to read the data/value horizontally. The code you see that below that's what I could execute!
SEE THE CODE BELOW:-
private void Form1_Load(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string text = "";
text = textBox1.Text;
string[] arr = text.Split(' ');
textBox2.Text = arr[5];
textBox3.Text = arr[8];
}
private void button3_Click(object sender, EventArgs e)
{
string file_name = "c:\\Excel\\count.txt";
string txtline = "";
System.IO.StreamReader objreader;
objreader = new System.IO.StreamReader(file_name);
do
{
txtline = txtline + objreader.ReadLine() + "\r\n";
txtline = txtline + objreader.ReadToEnd() + "";
this.textBox1.Text = "subzihut";
}
while (objreader.Peek() != -1);
textBox1.Text = txtline;
objreader.Close();
}
private void button2_Click(object sender, EventArgs e)
{
textBox4.Text = textBox2.Text + " " + textBox3.Text;
}
}
}
A textfile contains a sequence of characters, delimited by newline characters and probably other characters which are used as delimiters (usually a comma or a semiciolon).
When you read a file you simply read this stream of characters. There are helper functions which read such a file line-by-line (using the newline character as a delimiter).
In plain .Net there are no methods which read column-by-column.
So you should:
read the file line by line
split each line into fields/columns using string.Split() at the separator character(s)
access only the columns of interest
You can simply read the file line by line, splitt the lines and do whatever you want.
var lines = File.ReadLines(#"c:\yourfile.txt");
foreach(var line in lines)
{
var values = line.Split(' ');
}
public string getColumnString(int columnNumber){
string[] lines = System.IO.ReadAllLines(#"C:\inputfile.txt");
string stringTobeDisplayed = string.Empty;
foreach(string line in lines) {
if(columnNumber == -1){ //when column number is sent as -1 then read full line
stringTobeDisplayed += line +"\n"
}
else{ //else read only the column required
string [] words = line.Split();
stringTobeDisplayed += word[columnNumber] +"\n"
}
}
return stringTobeDisplayed;
}
Maybe this will help you:
public static void ReadFile(string path)
{
List<string> Col1 = new List<string>();
List<string> Col2 = new List<string>();
List<string> Col3 = new List<string>();
using (StreamReader sr = new StreamReader(path))
{
while (sr.EndOfStream)
{
string header = sr.ReadLine();
var values = header.Split(' ');
Col1.Add(values[0]);
Col2.Add(values[1]);
Col3.Add(values[2]);
}
}
}
It's true that sometimes you just don't know where to start. Here are some pointers.
You'll have to read the whole file in, probably using something like a StreamReader.
You can parse the first row into column names. Use StreamReader.ReadLine() to get the first line and then do some simple string parsing on it.
You'll want to create some kind of class/object to store and access your data.
Once you have column names, continue to parse the following lines into the proper arrays.
Some here's a rough idea
using(StreamReader sr = new StreamReadeR("C:\\my\\file\\location\\text.csv"))
{
string header = sr.ReadLine();
List<string> HeaderColumns = new List<string>(header.split(" ", StringSplitOptions.RemoveEmptyEntires));
myModelClass.Header = HeaderColumns;
etc...
You might also consider making some kind of dictionary to access columns by header name and index.

Ordering a comboBox by the int value

having a lot of problems ordering my combobox by value any help is greatly appreacitated
private void Form1_Load(object sender, EventArgs e)
{
//text to hold the conbo box, text is grabed from the AS2W14data.csv file from c:\temp\...
String variable;
variable = "";
//filll in the combo box , create a reader
System.IO.StreamReader sr = System.IO.File.OpenText(#"c:\temp\AS2W14data.csv");
//use a while loop to read the entire file line by line, using the current line to populate the comboBox
while (!sr.EndOfStream)
{
variable = sr.ReadLine();
string[] currentLineIndex = variable.Split(',');
//customer ID is indexed at the string array postion 1
//Customer name is indexed at the string array position 0
cboCustomer.Items.Add(currentLineIndex[1].Trim() + " " + currentLineIndex[0].Trim());
}
//close the file to prevent errors...
sr.Close();
}
this is my code so far and i cant seem to find a way to order it.. help
I would suggest ordering them before adding them to the combo. Also here's a little shortcut for reading a text file. First, you want to read lines by streaming them (ReadLines() returns IEnumerable<string>) into a projection (Select()) where you create an anonymous object with two properties - Id and Name. At the end, you order a collection of these anonymous objects by the Id.
var lines = File.ReadLines(#"c:\temp\AS2W14data.csv")
.Select(l => new
{
Id = int.Parse(l.Split(',')[1].Trim()),
Name = l.Split(',')[0].Trim()
}).OrderBy(i => i.Id);
foreach (var l in lines)
cboCustomer.Items.Add(l.Id + " " + l.Name);
try this code hope it will work alternatively you can use Sorted Property of ComboBox
private void Form1_Load(object sender, EventArgs e)
{
//text to hold the conbo box, text is grabed from the AS2W14data.csv file from c:\temp\...
String variable;
variable = "";
ArrayList Indexs = new ArrayList();
//filll in the combo box , create a reader
System.IO.StreamReader sr = System.IO.File.OpenText(#"c:\temp\AS2W14data.csv");
//use a while loop to read the entire file line by line, using the current line to populate the comboBox
while (!sr.EndOfStream)
{
variable = sr.ReadLine();
string[] currentLineIndex = variable.Split(',');
//customer ID is indexed at the string array postion 1
//Customer name is indexed at the string array position 0
Indexs.Add(new AddIndexValues(currentLineIndex[1].Trim() + " " + currentLineIndex[0].Trim());
}
//close the file to prevent errors...
cboCustomer.DataSource = DataBaseBuilds.Indexs;
sr.Close();
}
public class AddIndexValues
{
private int i_index;
public AddIndexValues(int Index)
{
i_index = Index;
}
public int Index
{
get { return i_index; }
}
}

Showing the values when form loaded

Hi all i have main form with a treeview control with a set of files displayed under each node. If i had my mouse over that node i will read the values that are present in the text file by using the following code
private void treeViewACH_NodeMouseHover(object sender, TreeNodeMouseHoverEventArgs e)
{
string strFile = string.Empty;
System.Text.StringBuilder messageBoxCS = new System.Text.StringBuilder();
messageBoxCS.AppendFormat(" {0}", e.Node);
strFile = messageBoxCS.ToString().Substring(11);
strFilePath = Directory.GetCurrentDirectory();
strFilePath = Directory.GetParent(strFilePath).ToString();
strFilePath = Directory.GetParent(strFilePath).ToString();
strFilePath = strFilePath + "\\ACH" + "\\" + strFile;
if ((File.Exists(strFilePath)))
{
StreamReader sr = new StreamReader(strFilePath);
StringComparison compareType = StringComparison.InvariantCultureIgnoreCase;
string fileName = Path.GetFileNameWithoutExtension(strFilePath);
string extension = Path.GetExtension(strFilePath);
if (fileName.StartsWith("FileHeader", compareType)
&& extension.Equals(".txt", compareType))
{
string s = sr.ReadToEnd();
StringBuilder sb = new StringBuilder();
//sb.Append("RecordTypeCode\tPriorityCode");
//sb.Append("\n");
//sb.Append("--------------------------------------------------");
//sb.Append("\n");
objFile.ReferenceTypeCode = s.Substring(0, 1);
sb.Append(objFile.ReferenceTypeCode);
string PriorCode = s.Substring(1, 2);
sb.Append(PriorCode);
objFile.getValues(sb.ToString());
frmTemp frmtemp = new frmTemp();
frmtemp.Show();
}
}
Now i would like to place the values in each textboxes on the form load. But as it is a different form i can not access the values from the business layer
I have coded like this on form load
BL.FileHeader objFile = new FileHeader();
private void frmTemp_Load(object sender, EventArgs e)
{
textBox1.Text = objFile.ReferenceTypeCode;
}
But i am unable to display the values any help please..
Add a property to your frmTemp class for each value that you want to display. In your NodeMouseHover handler, assign values to those properties right after you create the instance of the form. Then, in the frmTemp_Load handler, assign the values of those properties to the TextBox controls.
Got the answer by the following
frmTemp frmtmp = new frmTemp(strFileHeader);
frmtmp.Show();
public frmTemp(string str)
{
InitializeComponent();
if (str.StartsWith("1"))
{
this.textBox1.Text = str.Substring(0, 1);
}
else if (str.StartsWith("5"))
{
this.textBox1.Text = str.Substring(0, 1);
this.textBox2.Text = str.Substring(4, 16);
}
}

Categories