C# Objects in a list are overwriting each other [duplicate] - c#

This question already has answers here:
What does the static keyword mean?
(4 answers)
Closed 7 years ago.
The code I am looking at is as follows
string data;
string[] tokens;
while (sr.EndOfStream != true)
{
data = sr.ReadLine();
char delim = ',';
tokens = data.Split(delim);
Team t = new Team(tokens[0], int.Parse(tokens[1]), int.Parse(tokens[2]));
TeamList.Add(t);
}
//Test to make sure the teams were stored properly
foreach(Team t in TeamList)
{
Console.WriteLine(t.Name);
}
sr.Close();
When I use the foreach loop to write the team names out it displays 9 copies of Team9 (The teams are listed 1-9 in the text file line by line, with two numbers separated by commas to hold the wins and losses for each team, which is the reason there are delims with commas). This goes for any number of teams I add, if i add a 10th team it does 10 copies of team10, and if I use 8 teams it shows 8 copies of Team8. I added the foreach loop into the while loop to have it show the teams at each stage and it keeps overwriting all previous objects when it creates a new one, so for example the first time it runs the loop it shows Team1, then the next time it runs the loop it shows two lines of Team2, and so on. From my research I saw that this is usually caused by not declaring a new object inside of the loop, but in this case a new object is declared inside the loop.
Edit: the Team class is as follows
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApplication2
{
class Team
{
private static string tn;
private static int Wins, Losses;
public Team()
{
}
public Team(string name, int wins, int losses)
{
tn = name;
Wins = wins;
Losses = losses;
}
public override string ToString()
{
return tn + ", wins: " + Wins + ", losses: " + Losses;
}
public string Name
{
get { return tn; }
}
}
}
The TeamList variable and main class are as follows
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApplication2
{
class Program
{
private static Random pick = new Random();
private static List<Team> TeamList = new List<Team>();
static void Main(string[] args)
{
//Reading file io
Schedule(TeamList);
Console.ReadLine();
}
static void Schedule(List<Team> TeamList)
{
StreamReader sr = new StreamReader("C:/Users/andre/Desktop/VisualStudioProjects/ConsoleApplication1/ConsoleApplication1/TeamList.txt");
string data;
string[] tokens;
while (sr.EndOfStream != true)
{
data = sr.ReadLine();
char delim = ',';
tokens = data.Split(delim);
Team t = new Team(tokens[0], int.Parse(tokens[1]), int.Parse(tokens[2]));
TeamList.Add(t);
foreach(Team x in TeamList)
{
Console.WriteLine(x.Name);
}
}
//Test to make sure the teams were stored properly
foreach(Team t in TeamList)
{
Console.WriteLine(t.Name);
}
sr.Close();
}
The text file is simply a file that contains the following
Team1,0,0
Team2,0,0
Team3,0,0
Team4,0,0
Team5,0,0
Team6,0,0
Team7,0,0
Team8,0,0
Team9,0,0

You have
class Team
{
private static string tn; //STATIC??
private static int Wins, Losses; //STATIC??
}
static means the variable is shared between all instances of Team in your application. Remove it please. That is the problem.

Related

How to know class type when reading data from file?

I have 3 classes. 'Product' is the base class. 'Book' and 'Software' is the class that I inherit to 'Product' class. First I write it to file and I want to read it back to know whether it 'Book' or 'Software' class. Could anyone help me please?
Here is my code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
namespace ProductMainten
{
public class ProductDB
{
private const string dir = #"C:\C# 2012 Soben\Files\";
private const string path = dir + "ProductsCh14.txt";
public static List<Product> GetProducts()
{
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
StreamReader textIn = new StreamReader(
new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read));
List<Product> products = new List<Product>();
while (textIn.Peek() != -1)
{
string row = textIn.ReadLine();
string[] columns = row.Split('|');
Product product = new Product();
product.Code = columns[0];
product.Description = columns[1];
product.Price = Convert.ToDecimal(columns[2]);
products.Add(product);
}
textIn.Close();
return products;
}
public static void SaveProducts(List<Product> products)
{
StreamWriter textOut = new StreamWriter(
new FileStream(path, FileMode.Append, FileAccess.Write));
foreach (Product product in products)
{
if(product.GetType().Name == "Book")
{
WriteBook((Book)product, textOut);
}
else if(product.GetType().Name == "Software")
{
WriteSoftware((Software)product, textOut);
}
}
textOut.Close();
}
private static void WriteBook(Book product, StreamWriter textOut)
{
WriteBase(product, textOut);
textOut.Write(product.Author + "\n");
}
private static void WriteSoftware(Software product, StreamWriter textOut)
{
WriteBase(product, textOut);
textOut.Write(product.Version + "\n");
}
private static void WriteBase(Product product, StreamWriter textOut)
{
textOut.Write(product.Code + "|");
textOut.Write(product.Description + "|");
textOut.Write(product.Price + "|");
}
}
}
This is the code and for writing to file that's ok
It is not possible to determine the type from what I see, what you do is you write something like this:
MyCode|MyDescription|MyPrice|MyAdditionalProperty
There is no way you can detect type from this string unless there are some additional rules imposed on the inherited classes properties.
What you can do is add this information as your first element:
textOut.Write(product.GetType() + "|"); // You can write a switch instead to write your own string instead of a full name
Then when you read your data you first read the type moniker, after you do that you write a switch to create an instance of your class or use reflection if you write the full type.
P.S. I would suggest to look in some standardized libraries (or built-in methods) to do the serialization/deserialization instead of writing it yourself unless you have a good reason not not.

Trying to create a program using linked list for character counting?

I am trying to create a program that is a character counter using
a linked list and I am struggling. I have to program this in C#. If anyone can see a solution please tell me. I am have troubling using a linked list with nodes trying to show the results of counting characters. What am I missing? What do I need to add? By the way I am using visual works to run my code.
(First file)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApp17
{
class CharacterFrequency
{
private char ch;
private int frequency;
public char Ch
{
get { return ch; }
set { ch = value; }
}
public int Frequency
{
get { return frequency; }
set { frequency = value; }
}
}
}
(Second file)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApp17
{
class Program
{
static void Main(string[] args)
{
int ch;
const int InputFile = 0;
const int OutputFile = 1;
StreamReader reader = null;
StreamWriter writer = null;
//Declaring Linked List
CharacterFrequency obj = new CharacterFrequency();
LinkedList list = new LinkedList<CharacterFrequency>();
//To read the characters in the Input File.
reader = new StreamReader(File.OpenRead(args[InputFile]));
//To insert text through the loop.
while ((ch = reader.Read()) != -1)
{
//Creating my linked list.
CharacterFrequency cf = LinkedList<CharacterFrequency>
list(ch);
//Creating my nodes.
LinkedListNode<CharacterFrequency> node;
node = list.Find(cf);
//Conditions
if (node != null)
{
node.Value.Add(cf, 1); //Increase in increments.
}
else
{
list.AddLast(cf); //If it is not on the list yet, add it.
}
}
reader.Close();
//Create my output file.
writer = new StreamWriter(File.OpenWrite(args[OutputFile]));
//Display on prompt.
foreach (CharacterFrequency cf in list)
writer.WriteLine(cf.ToString());
writer.Close();
}
}
}

Automatic number insertion in MySQL with the format "AN-00000000"

My purpose on this is to insert a autonumber for this format AN-00000000 to the db, with the type in db varchar.
my code in windows form is saving a integer number already "10000000".
But I turn on my mind and think if possible that the auto number will be like this AN-00000000 and to save to the db with a character string.
I tried my best to change and apply but suddenly I can not implement because is on the integer part.
I am creating the basic system in our company to create a automate membership for the members, in our company we have 4 parts of membership which is Dep, sep, mep and cef, so I turn on my mind that i need to implement the 4 Id with the following to identify what the department they included. like DEP-00000001, SEP-00000001, MEP-0000001 and CEF-00000001.
Can anyone suggest or give their opinion on my code below? Thanks!
DBconnect.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data;
using MySql.Data.MySqlClient;
using System.Windows.Forms;
using System.Data;
namespace PAIRDevelopment.Classes
{
public class DBConnect
{
public static string csConnect = "uid=root; database=membership; pooling = false; convert zero datetime=True";
public static MySqlConnection csCon= new MySqlConnection(Classes.DBConnect.csConnect);
public MySqlCommand cmdCon = new MySqlCommand();
public MySqlDataReader reader;
public void nonQuery(string cmdText)
{
cmdCon.Connection = csCon;
csCon.Open();
cmdCon.CommandText = cmdText;
cmdCon.ExecuteNonQuery();
cmdCon.Dispose();
csCon.Close();
}
public void OPEN(string cmdtext)
{
cmdCon.Connection = Classes.DBConnect.csCon;
Classes.DBConnect.csCon.Open();
cmdCon.CommandText = cmdtext;
reader = cmdCon.ExecuteReader();
}
public void CLOSE()
{
reader.Close();
cmdCon.Dispose();
Classes.DBConnect.csCon.Close();
}
}
}
Windows Form:
using System;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
namespace PAIRDevelopment
{
public partial class Pair_Individual : Form
{
Classes.DBConnect OpenConCls = new Classes.DBConnect();
public Pair_Individual()
{
InitializeComponent();
textBox6.MaxLength = 13;
}
private void benabled_Click(object sender, EventArgs e)
{
OpenConCls.OPEN("SELECT MAX(piId) FROM tblpair_individual_membership");
while (OpenConCls.reader.Read())
{
string pcount = OpenConCls.reader[0].ToString();
if (pcount.Length == 0)
{
textBox1.Text = "10000000";
}
else
{
//int pcount1 = Convert.ToInt32(pcount);
//int pcountAdd = pcount1 + 1;
int pcount1 = Convert.ToInt32(pcount);
int pcountAdd = pcount1 + 1;
textBox1.Text = pcountAdd.ToString();
}
}
OpenConCls.CLOSE();
}
int pcount1 = Convert.ToInt32(pcount);
You are probably throwing a FormatException on the above line now if the string contains more than 0-9.
FormatException - value does not consist of an optional sign followed by
a sequence of digits (0 through 9).
If you know the first 4 chars will always be "XXX-" (e.g. "MEP-") then why don't you:
int pcount1 = Convert.ToInt32(pcount.Substring(4)); // ######## part
int pcountAdd = pcount1 + 1; // ######## + 1
textBox1.Text = String.Format("{0}-{1:D8}", pcount.Substring(0, 4), pcountAdd);
Which will convert only the numeric part, increment it, and then concatenate it with the first part.
Also you can look into the TryParse method. Which will indicate if your parse succeeded.
TryParse - Converts the string representation of a number to its 32-bit signed
integer equivalent. A return value indicates whether the operation succeeded.

find images url inside string

my program is intended to search for images url inside a string according to specific keywords. it actually works fine, only problem is the "search not found" error.
for some reason its like the code doesn't get to this "if" and wont return any error if there is no match found (last if).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Text.RegularExpressions;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
using (WebClient client = new WebClient())
{
int count = 0;
Regex SearchItem = new Regex("http://.+?\\.jpg");
string SearchValue = "fgdfgdf";
string htmlCode = "fsdflkjsdfkjsdfkjdsflkhttp://www.dssdtanya.jpgfsdf;ldsmfs;dlfms;dmfs";
Match matches = SearchItem.Match(htmlCode);
while (matches.Success)
{
string test = matches.ToString();
if (test.Contains(SearchValue))
{
count++;
Console.WriteLine("Result #{0}: '{1}' found in the source code at position {2}.",count, matches.Value, matches.Index);
matches = matches.NextMatch();
}
}
Console.WriteLine(count);
if (count == 0) { Console.WriteLine("search not found."); }
Console.ReadKey();
}
}
}
}
Your program enters an infinite loop if the first test doesn't contain the search value. Change your code to this:
while (matches.Success)
{
string test = matches.ToString();
if (test.Contains(SearchValue))
{
count++;
Console.WriteLine("Result #{0}: '{1}' found in the source code at position {2}.", count, matches.Value, matches.Index);
}
matches = matches.NextMatch(); //moved this outside the if
}

DownloadFileAsync multiple files using webclient

Description
Download multiple files using webclient's DownloadFileAsync and utilizing a text file for URL input for download.
Problem
The approach that I have used won't download files at all. Just runs and does nothing. It fills the list array then quits the program without downloading a single file. I have googled for solutions but come up shorthanded. Then attempted to search for a solution in the database here with same results. Any help is appreciated.
Questions
Why does this approach not work?
What can I do to improve this and learn from this.
Code
DownloadClass.cs
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Windows.Forms;
namespace ThreadTest
{
class DownloadClass
{
public struct download
{
public static string URL { get; set; }
public static string file { get; set; }
public static string[] link;
public static int downloadcount;
}
public static List<string> list = new List<string>();
public static WebClient wc = new WebClient();
public static void Download()
{
int count = 0;
download.URL = list[0];
Uri URI = new Uri(download.URL);
UriBuilder uri = new UriBuilder(URI);
download.link = uri.Path.ToLower().Split(new char[] { '/' });
count = 0;
// Find file
foreach (string abs in download.link)
{
count++;
if (abs.ToLower().Contains(".html") || abs.ToLower().Contains(".exe") || abs.ToLower().Contains(".txt"))
{
try
{
download.file = download.link[count];
wc.Proxy = null;
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
wc.DownloadFileAsync(URI, Application.StartupPath + "\\" + download.file);
break;
}
catch (Exception)
{ }
}
}
}
public static void BeginDownload()
{
new Thread(Download).Start();
}
public static void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
int count = 0;
download.downloadcount++;
download.URL = list[0];
Uri URI = new Uri(download.URL);
UriBuilder uri = new UriBuilder(URI);
download.link = uri.Path.ToLower().Split(new char[] { '/' });
count = 0;
// Find file
foreach (string abs in download.link)
{
count++;
if (abs.ToLower().Contains(".html") || abs.ToLower().Contains(".exe") || abs.ToLower().Contains(".txt"))
{
try
{
download.file = download.link[count];
}
catch (Exception)
{ }
}
}
list.RemoveAt(0);
if (list.Count > 0)
{
wc.DownloadFileAsync(URI, list[download.downloadcount], Application.StartupPath + "\\" + download.file);
}
else
{
Console.WriteLine("Downloading is done.");
Environment.Exit(0);
}
}
}
}
Program.cs (Main Class)
using System;
using System.IO;
using System.Collections.Generic;
using System.Windows.Forms;
namespace ThreadTest
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine("Usage: {0} <download txtfile>", Environment.GetCommandLineArgs()[0]);
Environment.Exit(0);
}
int counter = 0;
string line;
string format = string.Format("{0}\\{1}", Application.StartupPath, args[0]);
// Read the file line by line.
using(StreamReader file = new StreamReader(format))
{
while ((line = file.ReadLine())!= null)
{
// Store urls in a list.
DownloadClass.list.Add(line);
counter++;
}
}
DownloadClass.BeginDownload();
}
}
}
Besides being bad design there are lots of issues that lead to your code not (or nor correctly working).
You need to make sure that you application lives while it downloads something. Your current app quits right away (you have to wait for the downloading to complete in your main).
You application may download the same file multiple times but not download others at all (You need to completely lock object when they are used in an async=multithreading way like here when accessing static objects) BTW: Don't use static objects at all to avoid that in the first place.
Even if 2 is corrected it may still download the same file multiple times into the same filename and thus fail.
As long as you have no knowledge about multithreading I'd recommend you use the synchoneous methods to avoid all those problems.

Categories

Resources