I have created 2 classes. One class has instance variables, default constructor, constructor with parameters, properties and one function/method. the second class, contains my main method and is required to read data from a txt. file and then save the data to the 3 different objects.
I created 3 objects that look like this
NewEmployee employee1 = new NewEmployee();
this is what my code looks like to read the text file
using (StreamReader stream = new StreamReader(#"C:\Users/path))
{
while((line = stream.ReadLine()) != null)
{
Console.WriteLine(line);
}
How do I save the data from the text file to each object?
This is what the text file looks like:
First Name
Last Name
IdNUm
Start Year
Initial Salary
repeats 2x
I think this is what the OP wants:
List<Employee> employees = new List<Employee>();
using (StreamReader sr = new StreamReader("filepath"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
string[] split = line.Split(" ".ToCharArray());
employees.Add(new Employee
{
FirstName = split[0],
LastName = split[1],
EmployeedID = Int32.Parse(split[2]),
StartYear = Int32.Parse(split[3]),
InitialSalary = Decimal.Parse(split[4])
});
}
}
This assumes the lines are delimited by space and that the values will cast into the proper types. You can add the error handling but this will get you started.
Related
I am trying to read text file and store the information into the List<>.
So far, I managed to read strings off the file and split it, but having trouble storing the information onto the List<>. Perhaps I am trying to do too many things under one function.
using System.IO;
private void openFileDialog_Click(object sender, EventArgs e)
{
if (myOpenFileDialog.ShowDialog() == DialogResult.OK) ;
using (FileStream fStream = File.OpenRead(myOpenFileDialog.FileName))
{
StreamReader reader;
reader = new StreamReader(fStream);
string line;
while ((line = reader.ReadLine()) != null)
{
string[] playerInfo = line.Split(';');
int ID = int.Parse(playerInfo[0]);
string firstName = playerInfo[1];
string lastName = playerInfo[2];
DateTime dob = DateTime.Parse(playerInfo[3]);
List<Player> players = new List<Player>
players.add(new Player(id, firstName, lastName, dob);
}
}
}
When I check with MessageBox.Show, it comes out with 0 for the amount of lines I have in the file...
Perhaps my list.add code is in wrong place.
Thank you for your help and your time
You're creating a new List every time you're iterating over a new line, that's probably why you're not getting the correct amount of lines.
I also saw you have a few sintax errors in your code, I'll asume that you didn't copy/paste the code directly from the source and that's the reason of those errors (The Add method is in uppercase, and you missed the parentheses when initializing the List)
The working code would be like this:
List<Player> players = new List<Player>();
while ((line = reader.ReadLine()) != null) {
string[] playerInfo = line.Split(';');
int ID = int.Parse(playerInfo[0]);
string firstName = playerInfo[1];
string lastName = playerInfo[2];
DateTime dob = DateTime.Parse(playerInfo[3]);
players.Add(new Player(id, firstName, lastName, dob);
}
If you want to have access to the list more globally you could do it this way:
Let's assume your class name is Sample:
public class Sample {
// Declare the list as a private field
private List<Player> players;
// Constructor - Creates the List instance
public Sample() {
players = new List<Player>();
}
private void openFileDialog_Click(object sender, EventArgs e) {
players.Clear(); //Clears the list
if (myOpenFileDialog.ShowDialog() == DialogResult.OK) ;
using (FileStream fStream = File.OpenRead(myOpenFileDialog.FileName)) {
StreamReader reader;
reader = new StreamReader(fStream);
string line;
while ((line = reader.ReadLine()) != null) {
string[] playerInfo = line.Split(';');
int ID = int.Parse(playerInfo[0]);
string firstName = playerInfo[1];
string lastName = playerInfo[2];
DateTime dob = DateTime.Parse(playerInfo[3]);
players.Add(new Player(id, firstName, lastName, dob);
}
}
}
}
Declaring the list this way you'll be able to get the values of the list from other methods inside the same class.
I have a data file
Name; LastName; EurosCents;
Name2; LastName2; EurosCents2;
(for example:
John; Smith; 4,20;
Josh; Peck; 6,50;
)
I need to read the data and then do some further work with it... Is there any way to read the lines and save them? As the only way to read from a text file is to read the entire line at once.
var lst = File.ReadAllLines(yourFilePath).Select(x => new
{
FirstName = x.Split(';')[0]
LastName = x.Split(';')[1]
Value = decimal.Parse(x.Split(';')[2])
}).ToList();
use
lst[7].FirstName = "xxx";
Console.WriteLine(lst[2].Value);
etc...
The File API provide multiple options for reading files. Below is a possible way to proceed:
foreach(var line in File.ReadAllLines(path))
{
var splitted = line.Split(';');
var name = splitted.ElementAtOrDefault(0);
var lastName = splitted.ElementAtOrDefault(1);
var cents = Decimal.Parse(splitted.ElementAtOrDefault(2));
}
Parsing will be very easy if you are comfortable using LINQ.
Below line can get you the file in a hierarchical structure.
var theselines = File.ReadLines(#"C:\Test.txt").Select(l => l.Split(','));
You can see the result of above line by debugging.
Later you can have any logic to get the required data from each line without using foreach loop.
var Data = theselines.Select(l => new
{
id = l.Where(t => t.Contains("01")).FirstOrDefault(),
Price = l.Where(t => t.Contains(",")).FirstOrDefault(),
Firstname= l[0],
lastname = l[1]
});
Providing that data itself (both names and cents) can't contain ; in order to get
items from the comma separated values you can just split:
var data = File
.ReadLines(#"C:\MyData.csv")
// .Skip(1) // <- in case you have caption to skip
.Select(line => line.Split(';'))
.Select(items => new {
Name = items[0],
LastName = items[1],
EuroCents = decimal.Parse(items[2]) //TODO: check type and its format
});
//.ToArray(); // <- if you want to materialize as, say, an array
Then you can use it
foreach (var item in data) {
if (item.EuroCents > 10) {
...
}
}
the simple code to read whole file is as follows
string[] test(string path)
{
System.IO.StreamReader sr = new System.IO.StreamReader(path);
string[] str = sr.ReadToEnd().Split(';');
sr.Close();
return str;
}
I have a flat file that I am reading in C# and then attempting to parse. I mean to store the account number in the flat file in an array.
AccountNumber | AccountName | DateCreated
1 | Bob | 1/1/2011
2 | Donna | 3/2/2013
3 | Jake | 2/21/2010
5 | Sally | 4/2/2014
So far this is what my splitting looks like:
//List<string[]> myArrayList = new List<string[]>();
using (StreamReader read = new StreamReader(#"C:\text\Accounts.txt"))
{
string line;
while ((line = read.ReadLine()) != null)
{
string[] parts = line.Split('|');
Console.WriteLine(parts[0]);
//myArrayList.Add(parts[0]);
}
}
How do I store everything that's printed in parts[0] in it's own array outside of the while loop? I've tried doing a list add but I keep getting errors for invalid arguments. I commented out the bits that don't work.
the following code reads the contents of the file, splits the lines, stores it in a list and finally displays the first column in a RichTextBox
private void button1_Click(object sender, EventArgs e)
{
List<string[]> myArrayList = new List<string[]>();
StreamReader read = new StreamReader(#"C:\test\Accounts.txt");
string line;
while ((line = read.ReadLine()) != null)
{
string[] parts = line.Split('|');
//Console.WriteLine(parts[0]);
myArrayList.Add(parts);
}
foreach (var account in myArrayList)
{
richTextBox1.Text = richTextBox1.Text + account[0].ToString() + Environment.NewLine;
}
}
I like MethodMan's suggestion:
// Class structure
public class Account
{
public int AccountNumber;
public string AccountName;
public DateTime DateCreated;
public Account(string[] info)
{
// This is all dependent that info passed in, is already valid data.
// Otherwise you need to validate it before assigning it
AccountNumber = Convert.ToInt32(info[0]);
AccountName = info[1];
DateCrated = DateTime.Parse(info[2]);
}
}
Your code using the class structure:
List<Account> myAccounts = new List<Account>();
using (StreamReader read = new StreamReader(#"C:\text\Accounts.txt"))
{
string line;
while ((line = read.ReadLine()) != null)
{
string[] parts = line.Split('|');
myAccounts.Add(new Account(parts));
}
}
// Do whatever you want after you have the list filled
Background on this project. It started as a simple homework assignment that required me to store 5 zip codes and their corresponding cities. When a user puts a Zip code in a textbox, a corresponding city is returned, and likewise the opposite can be done. I wrote the code to return these values, but then I decided I wanted to store ALL zip codes and their corresponding Cities in an external .csv, and store those values in arrays and run the code off that because if its worth doing, its worth overdoing! To clarify, this is no longer for homework, just to learn more about using external files in C#.
In the following code, I have called to open the file successfully, now I just need help in figuring out how to pull the data that is stored in two separate columns (one for city, one for zip code) and store them in two arrays to be acted upon by the for loop. Here is the code I have now. You can see how I have previously stored the other values in arrays and pulled them out:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnConvert2City_Click(object sender, EventArgs e)
{
try
{
string dir = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().Location);
string path = dir + #"\zip_code_database_edited.csv";
var open = new StreamReader(File.OpenRead(path));
int EnteredZipcode = Convert.ToInt32(txtZipcode.Text.Trim());
string result = "No Cities Found";
string[] Cities = new String[5] { "FLINTSTONE", "JAMAICA", "SCHENECTADY", "COTTONDALE", "CINCINNATI" };
int[] Zipcode = new int[5] { 30725, 11432, 12345, 35453, 45263 };
for (int i = 0; i <= Zipcode.Length - 1; i++)
{
if (Zipcode[i] == EnteredZipcode)
{
result = Cities[i];
break;
}
}
string DisplayState = result;
txtCity.Text = DisplayState;
}
catch (FormatException)
{
MessageBox.Show("Input must be numeric value.");
}
catch (OverflowException)
{
MessageBox.Show("Zipcode to long. Please Re-enter");
}
}
private void btnConvert2Zipcode_Click(object sender, EventArgs e)
{
string dir = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().Location);
string path = dir + #"\zip_code_database_edited.csv";
var open = new StreamReader(File.OpenRead(path));
String EnteredCity = txtCity.Text.ToUpper();
string result = "No Zipcode Found";
string[] Cities = new String[5] { "FLINTSTONE", "JAMAICA", "SCHENECTADY", "COTTONDALE", "CINCINNATI" };
int[] Zipcode = new int[5] { 30725, 11432, 12345, 35453, 45263 };
for (int i = 0; i <= Cities.Length - 1; i++)
{
if (Cities[i] == EnteredCity)
{
result = Convert.ToString(Zipcode[i]);
break;
}
}
string DisplayZip = result;
txtZipcode.Text = DisplayZip;
}
}
The following data is a snippet of what the data in my excel .csv looks like:
zip,primary_city
44273,Seville
44274,Sharon Center
44275,Spencer
44276,Sterling
44278,Tallmadge
44280,Valley City
44281,Wadsworth
44282,Wadsworth
44285,Wayland
And so on for about 46,000 rows.
How can I pull the zip and the primary_city into two separate arrays (I'm guessing with some ".Split "," "line) that my for-loop can operate on?
Also, if there are better ways to go about this, please let me know (but be sure to leave an explanation as I want to understand where you are coming from).
Don't create two separate array.Create a separate class for city
class City
{
public string Name{get;set;}
public int ZipCode{get;set;}
}
Now to read the data from that csv file
List<City> cities=File.ReadAllLines(path)
.Select(x=>new City
{
ZipCode=int.Parse(x.Split(',')[0]),
Name=x.Split(',')[1]
}).ToList<City>();
Or you can do this
List<City> cities=new List<City>();
foreach(String s in File.ReadAllLines(path))
{
City temp=new City();
temp.ZipCode=int.Parse(s.Split(',')[0]);
temp.Name=s.Split(',')[1];
cities.Add(temp);
}
You can try this:
string dir = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().Location);
string path = dir + #"\zip_code_database_edited.csv";
var open = new StreamReader(File.OpenRead(path));
var cities = new HashList<string>();
var zipCodes = new HashList<int>();
var zipAndCity = new string[2];
string line = string.Empty;
using (open)
{
while ((line = reader.ReadLine()) != null)
{
zipAndCity = line.Split(",");
zipCodes.Add(int.Parse(zipAndCity[0]));
cities.Add(zipAndCity[1]);
}
}
I am posting this answer having learned much more about C# since I posted this question. When reading a CSV, there are better options than String.Split().
The .NET Framework already has a built-in dedicated CSV parser called TextFieldParser.
It's located in the Microsoft.VisualBasic.FileIO namespace.
Not only are there many edge cases that String.Split() is not properly equipped to handle, but it's also much slower to use StreamReader.
I have a flat text file that contains the following data;
Following are the names and ages in a text file.
26|Rachel
29|Chris
26|Nathan
The data is kept on a server (e.g http://domain.com/info.dat), I'd like to read this text file and insert it into an array (age and name). I'd like to ignore the first line (Following are....).
I've sorted the code to grab the data file using a webclient and the code to open the dat file using streamreader as follows;
using (StreamReader sr = new StreamReader(path))
{
while (sr.Peek() >= 0)
{
string[] channels = Text.Split('|');
foreach (string s in channels)
{
}
}
}
The problem with the above code is when it comes to inputting it into an array with the correct columns. Could anyone give me some pointers?
Many thanks
How about an answer that uses some LINQ:
var results = from str in File.ReadAllLines(path).Skip(1)
where !String.IsNullOrEmpty(str)
let data = str.Split('|')
where data.Length == 2
select new Person { Age = Int32.Parse(data[0], NumberStyles.Integer, CultureInfo.CurrentCulture), Name = data[1] };
results is now IEnumerable<Person> which you can do ToList or ToArray on to get a List<Person> or Person[], or you can simply use the results with a foreach loop.
UPDATE: here is the Person class needed to make this more functional.
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
You could do something like this. (There is no error checking, you might want to check for errors when parsing the age etc.
class Person
{
string Name {get;set;}
int Age {get;set;}
}
List<Person> people = new List<Person>();
string line;
using (StreamReader sr = new StreamReader(path))
{
sr.ReadLine();
while ((line == sr.ReadLine()) != null)
{
string[] channels = line.Split('|');
people.Add(new Person() {Age=int.Parse(channels[0]), Name=channels[1]});
}
}
You should use Dictionary and not Array to store the data.
Sample code:
FileStream fs = new FileStream("filename");
Dictionary<int,string> dict = new Dictionary<int,string>();
string line = "";
fs.ReadLine(); //skip the first line
while( (line = fs.ReadLine()) != null)
{
string parts = line.split("|".ToCharArray());
dict.Add(int.Parse(parts[0]), parts[1]);
}