using System;
using System.IO;
using System.Collections;
namespace ReadFiles
{
class Program
{
static void Main(string[] args)
{
StreamReader objstream = new StreamReader("c:\\documents and settings\\btallos\\desktop\\Company.txt");
string sLine ="";
ArrayList arrText = new ArrayList();
while (sLine != null)
{
sLine = objstream.ReadLine();
if (sLine != null)
arrText.Add(sLine);
}
objstream.Close();
foreach (string sOutput in arrText)
Console.WriteLine(sOutput);
Console.ReadLine();
}
}
}
I wrote a console app that displays information from a local file on my desktop and displays the content within the file. I was wondering how can I create a function that can search for keywords and only display the words, I want it to search for?
Can anyone help me out?
You should use the generic List instead of an ArrayList. You can then use the Where method and provide a string to search for, like this:
var lines = File.ReadAllLines("filename").ToList(); // Read all lines and cast it to a List<string>
var matches = lines.Where(x => x == "query");
foerach(var match in matches)
{
Console.WriteLine(match);
}
This will find all items equal to your query.
You can easily expand this to search for items containing your query by switching x => x == "query" to x => x.Contains("query")
I would start with File.ReadAllText and the push on to System.Text.RegularExpressions.Regex
Fuzzy requirements, but this is the solution from what I understood:
var keywords = new string[] {"some", "keywords"};
var foundKeywords = File.ReadAllLines("filename").
SelectMany(line => keywords.Where(keyword => line.Contains(keyword))).
Distinct();
The criteria can be improved (with a regular expression, for example). Currently it will also return you the keywords that are substrings of other words.
I'm going to try to put this content into a database - And then search for the content I want it to display.
* ZIP Codes
* Area Codes
* City Name
* State Name
* Two digit State Code
* City Type
* City Alias Abbrev.
* County Name
* State FIPS
* County FIPS
* Time Zone
* Daylight Savings Indicator
* Number of Businesses
* Q1 Payroll
* Annual Payroll
* Number of Employees
* Employment Flag
* County Growth Rate
You could figure out how you want to highlight the text you want to search in a console app (say be pre/postpending $$search text$$). Open each document and run a regex replace. If that returns a string length different than original, you have matches. If you don't want to show the whole document, I would get 50 characters before, and 50 after for example, but that might take a bit more work. Crude, but simple.
Related
I have looked but failed to find a tutorial that would address my question. Perhaps I didn't word my searches correctly. In any event, I am here.
I have taken over a handyman company and he had about 150 customers. He had a program that he bought that produces records for his customers. I have the records, but he wouldn't sell me the program as it is commercial and he's afraid of going to prison for selling something like that... whatever... They are written in a text file. The format appears to be:
string name
string last_job_description
int job_codes
string job_address
string comments
The text file looks like this
*Henderson*
*Cleaned gutters, fed the lawn, added mulch to the front flower beds,
cut the back yard, edged the side walk, pressure washed the driveway*
*04 34 32 1 18 99 32 22 43 72 11 18*
*123 Anywhere ave*
*Ms.always pays cash no tip. Mr. gives you a check but always tips*
Alright.. My question is in C# I want to write a program to edit these records, add new customers and delete some I may lose, moves, or dies... But the 2nd entry is broken over two lines, sometimes 3 and 4 lines. They all start and end with *. So, how do I read the 2 to 4 lines and get them into the last_job_description string variable? I can write the class, I can read lines, I can trim away the asterisks. I can find nothing on reading multiple lines into a single variable.
Let's do it right!
First define the customer model:
public class Customer
{
public string Name { get; set; }
public string LastJobDescription { get; set; }
public List<int> JobCodes { get; set; }
public string JobAddress { get; set; }
public string Comments { get; set; }
}
Then, we need a collection of customers:
var customers = new List<Customer>();
Fill the collection with data from the file:
string text = File.ReadAllText("customers.txt");
string pattern = #"(?<= ^ \*) .+? (?= \* \r? $)";
var options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled
| RegexOptions.Singleline | RegexOptions.Multiline;
var matches = Regex.Matches(text, pattern, options);
for (int i = 0; i < matches.Count; i += 5)
{
var customer = new Customer
{
Name = matches[i].Value,
LastJobDescription = matches[i + 1].Value,
JobCodes = matches[i + 2].Value.Split().Select(s => int.Parse(s)).ToList(),
JobAddress = matches[i + 3].Value,
Comments = matches[i + 4].Value
};
customers.Add(customer);
}
I'm using a regular expression that allows to have the * character in the middle of the lines.
Now we can comfortably work with this collection.
Examples of usage.
Remove the first customer:
customers.RemoveAt(0);
Add a comment to the latest client:
customers.Last().Comments += " Very generous.";
Find the first record for a client by the name of Henderson and add the code of the job performed:
customers.Find(c => c.Name == "Henderson").JobCodes.Add(42);
Add new customer:
var customer = new Customer
{
Name = "Chuck Norris",
LastJobDescription= "Saved the world.",
JobCodes = new List<int>() { 1 },
JobAddress = "UN",
Comments = "Nice guy!"
};
customers.Add(customer);
And so on.
To save data to a file, use the following:
var sb = new StringBuilder();
foreach (var customer in customers)
{
sb.Append('*').Append(customer.Name).Append('*').AppendLine();
sb.Append('*').Append(customer.LastJobDescription).Append('*').AppendLine();
sb.Append('*').Append(string.Join(" ", customer.JobCodes)).Append('*').AppendLine();
sb.Append('*').Append(customer.JobAddress).Append('*').AppendLine();
sb.Append('*').Append(customer.Comments).Append('*').AppendLine();
}
File.WriteAllText("customers.txt", sb.ToString());
You probably need a graphical user interface. If so, I suggest you to ask a new question where you specify what you use: WinForms, WPF, Web-application or something else.
if you want to read all the lines in a file into a single variable then you need to do this
var txt = File.ReadAllText(.. your file location here ..);
or you can do
var lines = File.ReadAllLines(.. your file location here); and then you can iterate through each line and remove the blanks of leave as it is.
But based on your question the first line is what you're really after
when you should read last_job_description read second line. if it starts with * it means that this line is job_codes otherwise append it to pervous read line. do this fo every lines until you find job_codes.
using (var fileReader = new StreamReader("someFile"))
{
// read some pervous data here
var last_job_description = fileReader.ReadLine();
var nextLine = fileReader.ReadLine();
while (nextLine.StartsWith("*") == false)
{
last_job_description += nextLine;
nextLine = fileReader.ReadLine();
}
//you have job_codes in nextline, so parse it now and read next data
}
or you may even use the fact that each set of data starts and ENDS!!! with * so you may create function that reads each "set" and returns it as singleline string, no matter how much lines it really was. let's assume that reader variable you pass to this function is the same StreamReader as in upper code
function string readSingleValue(StreamReader fileReader){
var result = "";
do
{
result += fileReader.ReadLine().Trim();
} while (result.EndsWith("*") == false);
return result;
}
I think your problem is little complex. What i am trying to say is it doesn't mention to a specific problem. It is contained at least 3 different programming aspects that you need to know or learn to reach your goal. The steps that you must take are described below.
unfortunately you need to consider your current file as huge string type.
Then you are able to process this string and separate different parts.
Next move is defining a neat, reliable and robust XML file which can hold your data.
Fill your xml with your manipulated string.
If you have a xml file you can simply update it.
There is not built-in method that will parse your file exactly like you want, so you have to get your hands dirty.
Here's an example of a working code for your specific case. I assumed you wanted your job_codes in an array since they're multiple integers separated by spaces.
Each time we encounter a line starting with '*', we increase a counter that'll tell us to work with the next of your properties (name, last job description, etc...).
Each line is appended to the current property.
And obviously, we remove the stars from the beginning and ending of every line.
string name = String.Empty;
string last_job_description = String.Empty;
int[] job_codes = null;
string job_address = String.Empty;
string comments = String.Empty;
int numberOfPropertiesRead = 0;
var lines = File.ReadAllLines("C:/yourfile.txt");
for (int i = 0; i < lines.Count(); i++)
{
var line = lines[i];
bool newProp = line.StartsWith("*");
bool endOfProp = line.EndsWith("*");
if (newProp)
{
numberOfPropertiesRead++;
line = line.Substring(1);
}
if (endOfProp)
line = line.Substring(0, line.Length - 1);
switch (numberOfPropertiesRead)
{
case 1: name += line; break;
case 2: last_job_description += line; break;
case 3:
job_codes = line.Split(' ').Select(el => Int32.Parse(el)).ToArray();
break;
case 4: job_address += line; break;
case 5: comments += line; break;
default:
throw new ArgumentException("Wow, that's too many properties dude.");
}
}
Console.WriteLine("name: " + name);
Console.WriteLine("last_job_description: " + last_job_description);
foreach (int job_code in job_codes)
Console.Write(job_code + " ");
Console.WriteLine();
Console.WriteLine("job_address: " + job_address);
Console.WriteLine("comments: " + comments);
Console.ReadLine();
I have created a dictionary, and created code to read a txt file, and input each word from the file into the dictionary.
//Set up OpenFileDialog box, and prompt user to select file to open
DialogResult openFileResult;
OpenFileDialog file = new OpenFileDialog() ;
file.Filter = "txt files (*.txt)|*.txt";
openFileResult = file.ShowDialog();
if (openFileResult == DialogResult.OK)
{
//If user selected file successfully opened
//Reset form
this.Controls.Clear();
this.InitializeComponent();
//Read from file, split into array of words
Stream fs = file.OpenFile();
StreamReader reader;
reader = new StreamReader(fs);
string line = reader.ReadToEnd();
string[] words = line.Split(' ', '\n');
//Add each word and frequency to dictionary
foreach (string s in words)
{
AddToDictionary(s);
}
//Reset variables, and set-up chart
ResetVariables();
ChartInitialize();
foreach (string s in wordDictionary.Keys)
{
//Calculate statistics from dictionary
ComputeStatistics(s);
if (dpCount < 50)
{
AddToGraph(s);
}
}
//Print statistics
PrintStatistics();
}
And the AddToDictionary(s) function is:
public void AddToDictionary(string s)
{
//Function to add string to dictionary
string wordLower = s.ToLower();
if (wordDictionary.ContainsKey(wordLower))
{
int wordCount = wordDictionary[wordLower];
wordDictionary[wordLower] = wordDictionary[wordLower] + 1;
}
else
{
wordDictionary.Add(wordLower, 1);
txtUnique.Text += wordLower + ", ";
}
}
The text file being read by this program is:
To be or not to be that is the question
Whether tis nobler in the mind to suffer
The slings and arrows of outrageous fortune
Or to take arms against a sea of troubles
And by opposing end them To die to sleep
No more and by a sleep to say we end
The heartache and the thousand natural shocks
That flesh is heir to Tis a consummation
Devoutly to be wished To die to sleep
To sleep perchance to dream ay theres the rub
For in that sleep of death what dreams may come
When we **have** shuffled off this mortal coil
Must give us pause Theres the respect
That makes calamity of so long life
For who would bear the whips and scorns of time
The oppressors wrong the proud mans contumely
The pangs of despised love the laws delay
The insolence of office and the spurns
That patient merit of th unworthy takes
When he himself might his quietus make
With a bare bodkin Who would fardels bear
To grunt and sweat under a weary life
But that the dread of something after death
The undiscovered country from whose bourn
No traveller returns puzzles the will
And makes us rather bear those ills we **have**
Than fly to others that we know not of
Thus conscience does make cowards of us all
And thus the native hue of resolution
Is sicklied oer with the pale cast of thought
And enterprise of great pitch and moment
With this regard their currents turn awry
And lose the name of action Soft you now
The fair Ophelia Nymph in thy orisons
Be all my sins remembered
The problem I am encountering is that the word "have" is appearing twice in the dictionary. I know this doesn't happen with dictionaries, but for some reason it is appearing twice. Does anyone know why this would happen?
If you run:
var sb = new StringBuilder();
sb.AppendLine("test which");
sb.AppendLine("is a test");
var words = sb.ToString().Split(' ', '\n').Distinct();
Inspecting words in the debugger shows that some instances of "test" have acquired a \r due to the two byte CRLF line terminator - which isn't treated by the split.
To fix, change your split to:
Split(new[] {" ", Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
Splitting text into words is generally hard solution if you want to support multiple languages. Regular expressions are generally better in dealing with parsing than basic String.Split.
I.e. in your case you are picking up variations of "new line" as part of a word, you also could be picking up things like non-breaking space,...
Following code will pick words better than your current .Split, for more info - How do I split a phrase into words using Regex in C#
var words = Regex.Split(line, #"\W+").ToList();
Additionally you should make sure your dictionary is case insensitive like following (pick comparer based on your needs, there are culture-aware once too):
var dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase);
I would be inclined to change the following code:
//Read from file, split into array of words
Stream fs = file.OpenFile();
StreamReader reader;
reader = new StreamReader(fs);
string line = reader.ReadToEnd();
string[] words = line.Split(' ', '\n');
//Add each word and frequency to dictionary
foreach (string s in words)
{
AddToDictionary(s);
}
to this:
wordDictionary =
File
.ReadAllLines(file)
.SelectMany(x => x.Split(new [] { ' ', }, StringSplitOptions.RemoveEmptyEntries))
.Select(x => x.ToLower())
.GroupBy(x => x)
.ToDictionary(x => x.Key, x => x.Count());
This completely avoids the issues with line endings and also has the added advantage that it doesn't leave any undisposed streams lying around.
Currently fiddling with a little project I'm working on, it's a count down type game (the tv show).
Currently, the program allows the user to pick a vowel or consonant to a limit of 9 letters and then asks them to input the longest word they can think of using these 9 letters.
I have a large text file acting as a dictionary that i search through using the user inputted string to try match a result to check if the word they entered is a valid word. My problem, is that I want to then search my dictionary for the longest word made up of the nine letters, but i just cant seem to find a way to implement it.
So far I've tried putting every word into an array and searching through each element to check if it contains the letters but this wont cover me if the longest word that can be made out of the 9 letters is a 8 letter word. Any idea's?
Currently I have this (This is under the submit button on the form, sorry for not providing code or mentioning it's a windows form application):
StreamReader textFile = new StreamReader("C:/Eclipse/Personal Projects/Local_Projects/Projects/CountDown/WindowsFormsApplication1/wordlist.txt");
int counter1 = 0;
String letterlist = (txtLetter1.Text + txtLetter2.Text + txtLetter3.Text + txtLetter4.Text + txtLetter5.Text + txtLetter6.Text + txtLetter7.Text + txtLetter8.Text + txtLetter9.Text); // stores the letters into a string
char[] letters = letterlist.ToCharArray(); // reads the letters into a char array
string[] line = File.ReadAllLines("C:/Eclipse/Personal Projects/Local_Projects/Projects/CountDown/WindowsFormsApplication1/wordlist.txt"); // reads every line in the word file into a string array (there is a new word on everyline, and theres 144k words, i assume this will be a big performance hit but i've never done anything like this before so im not sure ?)
line.Any(x => line.Contains(x)); // just playing with linq, i've no idea what im doing though as i've never used before
for (int i = 0; i < line.Length; i++)// a loop that loops for every word in the string array
// if (line.Contains(letters)) //checks if a word contains the letters in the char array(this is where it gets hazy if i went this way, i'd planned on only using words witha letter length > 4, adding any words found to another text file and either finding the longest word then in this text file or keeping a running longest word i.e. while looping i find a word with 7 letters, this is now the longest word, i then go to the next word and it has 8 of our letters, i now set the longest word to this)
counter1++;
if (counter1 > 4)
txtLongest.Text += line + Environment.NewLine;
Mike's code:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
static void Main(string[] args) {
var letters = args[0];
var wordList = new List<string> { "abcbca", "bca", "def" }; // dictionary
var results = from string word in wordList // makes every word in dictionary into a seperate string
where IsValidAnswer(word, letters) // calls isvalid method
orderby word.Length descending // sorts the word with most letters to top
select word; // selects that word
foreach (var result in results) {
Console.WriteLine(result); // outputs the word
}
}
private static bool IsValidAnswer(string word, string letters) {
foreach (var letter in word) {
if (letters.IndexOf(letter) == -1) { // checks if theres letters in the word
return false;
}
letters = letters.Remove(letters.IndexOf(letter), 1);
}
return true;
}
}
Here's an answer I knocked together in a couple of minutes which should do what you want. As others have said, this problem is complex and so the algorithm is going to be slow. The LINQ query evaluates each string in the dictionary, checking whether the supplied letters can be used to produce said word.
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args) {
var letters = args[0];
var wordList = new List<string> { "abcbca", "bca", "def" };
var results = from string word in wordList
where IsValidAnswer(word, letters)
orderby word.Length descending
select word;
foreach (var result in results) {
Console.WriteLine(result);
}
}
private static bool IsValidAnswer(string word, string letters) {
foreach (var letter in word) {
if (letters.IndexOf(letter) == -1) {
return false;
}
letters = letters.Remove(letters.IndexOf(letter), 1);
}
return true;
}
}
So where are you getting stuck? Start with the slow brute-force method and just find all the words that contain all the characters. Then order the words by length to get the longest. If you don't want to return a word that is shorter than the number of characters being sought (which I guess is only an issue if there are duplicate characters???), then add a test and eliminate that case.
I've had some more thoughts about this. I think the way to do it efficiently is by preprocessing the dictionary, ordering the letters in each word in alphabetical order and ordering the words in the list alphabetically too (you'll probably have to use some sort of multimap structure to store the original word and the sorted word).
Once you've done that you can much more efficiently find the words that can be generated from your pool of letters. I'll come back and flesh out an algorithm for doing this later, if someone else doesn't beat me to it.
Step 1: Construct a trie structure with each word sort by letter.
Example: EACH is sorted to ACEH is stored as A->C->E->H->(EACH, ACHE, ..) in the trie (ACHE is an anagram of EACH).
Step 2: Sort the input letters and find find the longest word corresponding to that set of letters in the trie.
Have you tried implementing something like this? It would be great to see your code you have tried.
string[] strArray = {"ABCDEFG", "HIJKLMNOP"};
string findThisString = "JKL";
int strNumber;
int strIndex = 0;
for (strNumber = 0; strNumber < strArray.Length; strNumber++)
{
strIndex = strArray[strNumber].IndexOf(findThisString);
if (strIndex >= 0)
break;
}
System.Console.WriteLine("String number: {0}\nString index: {1}",
strNumber, strIndex);
This must do the job :
private static void Main()
{
char[] picked_char = {'r', 'a', 'j'};
string[] dictionary = new[] {"rajan", "rajm", "rajnujaman", "rahim", "ranjan"};
var words = dictionary.Where(word => picked_char.All(word.Contains)).OrderByDescending(word => word.Length);
foreach (string needed_words in words)
{
Console.WriteLine(needed_words);
}
}
Output :
rajnujaman
ranjan
rajan
rajm
I'm running three counters, one to return the total amount of chars, one to return the number of '|' chars in my .txt file (total). And one to read how many separate lines are in my text file. I'm assuming my counters are wrong, I'm not sure. In my text file there are some extra '|' chars, but that is a bug I need to fix later...
The Message Boxes show
"Lines = 8"
"Entries = 8"
"Total Chars = 0"
Not sure if it helps but the .txt file is compiled using a streamwriter, and I have a datagridview saved to a string to create the output. Everything seems okay with those functions.
Here is a copy of the text file I'm reading
Matthew|Walker|MXW320|114282353|True|True|True
Audrey|Walker|AXW420|114282354|True|True|True
John|Doe|JXD020|111222333|True|True|False
||||||
And here is the code.
private void btnLoadList_Click(object sender, EventArgs e)
{
var loadDialog = new OpenFileDialog
{
InitialDirectory = Convert.ToString(Environment.SpecialFolder.MyDocuments),
Filter = "Text (*.txt)|*.txt",
FilterIndex = 1
};
if (loadDialog.ShowDialog() != DialogResult.OK) return;
using (new StreamReader(loadDialog.FileName))
{
var lines = File.ReadAllLines(loadDialog.FileName);//Array of all the lines in the text file
foreach (var assocStringer in lines)//For each assocStringer in lines (Runs 1 cycle for each line in the text file loaded)
{
var entries = assocStringer.Split('|'); // split the line into pieces (e.g. an array of "Matthew", "Walker", etc.)
var obj = (Associate) _bindingSource.AddNew();
if (obj == null) continue;
obj.FirstName = entries[0];
obj.LastName = entries[1];
obj.AssocId = entries[2];
obj.AssocRfid = entries[3];
obj.CanDoDiverts = entries[4];
obj.CanDoMhe = entries[5];
obj.CanDoLoading = entries[6];
}
}
}
Hope you guys find the bug(s) here. Sorry if the formatting is sloppy I'm self-taught, no classes. Any extra advice is welcomed, be as honest and harsh as need be, no feelings will be hurt.
In summary
Why is this program not reading the correct values from the text file I'm using?
Not totally sure I get exactly what you're trying to do, so correct me if I'm off, but if you're just trying to get the line count, pipe (|) count and character count for the file the following should get you that.
var lines = File.ReadAllLines(load_dialog.FileName);
int lineCount = lines.Count();
int totalChars = 0;
int totalPipes = 0; // number of "|" chars
foreach (var s in lines)
{
var entries = s.Split('|'); // split the line into pieces (e.g. an array of "Matthew", "Walker", etc.)
totalChars += s.Length; // add the number of chars on this line to the total
totalPipes = totalPipes + entries.Count() - 1; // there is always one more entry than pipes
}
All the Split() is doing is breaking the full line into an array of the individual fields in the string. Since you only seem to care about the number of pipes and not the fields, I'm not doing much with it other than determining the number of pipes by taking the number of fields and subtracting one (since you don't have a trailing pipe on each line).
I currently got a problem with RCon.
I am basically sending a request to receive a list of all players.
The server answers with a list of all players like this:
# IP:Port Ping ID Name
0 127.0.0.1 0 3523523 Bob
12 192.168.0.1 120 342525523 Anna
320 192.168.0.2 240 63463634634 Chuck Norris
^^^ ^^ ^^^^^ ^
The problem is, I do not know how many spaces are between the different tags, it depends on how long the #/IP/ping and ID is.
The spaces can differ from 1 space to 5 spaces.
Also there can be spaces in the name so I can't just split with one space.
I want to read the IP, ping, id and name from the list.
I currently try to do some messy replace & split stuff but it just doesn't work out when the spaces are different.
I thought about doing something with regex but I am not so good with regex.
I already split the lines to cut it down to 1 line.
The class Player can store all the informations
Here is what should happen:
// List to store all the players
List<Player> players = new List<Player>();
// Using a StringReader to split up every line
StringReader reader = new StringReader(result);
string line;
int row = 0;
// Processing every line one after another
while ((line = reader.ReadLine()) != null)
{
row++;
// Doing some filtering to prevent empty lines and other stuff
if (row > 3 && !line.StartsWith("(") && line.Length > 0)
{
// Getting all the stuff I need here
// Then adding a player object to save the informations, ignore status
players.Add(new Player(ip, ping, id, name, status));
}
}
Anyone got an idea that could solve this?
I want to read the IP, ping, id and name from the list.
I very rarely say this but... this sounds like a job for regular expressions. If you're not good at them at the moment, use this as an opportunity to learn :)
Use a regular expression to match everything, capturing each value in a group, then fetch the groups afterwards.
Sample code:
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
class Test
{
static void Main()
{
var regex = new Regex(#"^(?:\d+)\s+(?<ip>[\d.]+)\s+(?<ping>\d+)\s+(?<id>\d+)\s+(?<name>.*)$");
var query = File.ReadLines("data.txt")
.Skip(1)
.Select(line => regex.Match(line))
.Select(match => new {
IP = match.Groups["ip"].Value,
Ping = match.Groups["ping"].Value,
Id = match.Groups["id"].Value,
Name = match.Groups["name"].Value
});
foreach (var entry in query)
{
Console.WriteLine(entry);
}
}
}
Sample output:
{ IP = 127.0.0.1, Ping = 0, Id = 3523523, Name = Bob }
{ IP = 192.168.0.1, Ping = 120, Id = 342525523, Name = Anna }
{ IP = 192.168.0.2, Ping = 240, Id = 63463634634, Name = Chuck Norris }
Obviously you can parse the text for the ping, IP address etc. This was just to get you started. (Also, you should probably check for the success of the match...)
Simplest way would be to split your line into 5 parts
var items = line.Split(new char[] {' '}, 5, StringSplitOptions.RemoveEmptyEntries);
players.Add(new Player(items[1], items[2], items[3], items[4], "status?"));