from textbox inside winform I'm taking user input as csv and I'm putting them into string array where I iterate trough that array to create some object with first and last names.
if(txtAuthors.Text != string.Empty)
{
if(txtAuthors.Text.Contains(","))
{
if (authorsInput.Count() > 0)
{
foreach (string name in authorsInput)
{
name.TrimStart();
string[] firstAndLastName = name.Split(' ');
string fname = firstAndLastName[0];
string lname = firstAndLastName[1];
}
}
}
}
Problem is that only first author before first comma is added as it should (fname and lname) and other only lastname. So I've tried as you can see to trim name to remove whitespace from array members but problem is still the same.
What I'm doing wrong here?
update:this now works
string[] firstAndLastName = name.TrimStart().Split(' ');
but I still don't know why this don't work
name.TrimStart();
string[] firstAndLastName = name.Split(' ');
Calling name.TrimStart() doesn't result in a variable name without initial blanks because strings are immutable objects.
You cannot modify a string in place. You always need to assign the result of the operation to a new string.
Your second option works because it is like:
string newname = name.TrimStart();
string[] firstAndLastName = newname.Split(' ');
Also, notice that I use a new variable for the result of the TrimStart. This is required if you do that inside the foreach loop because it is not allowed to change the foreach iteration variable
You can use Trim() cuts all whitespaces before and after
'fname = fname.Trim();'
Related
I opened a text file and showed it in a listbox (lstArchivo) every string is divided by a semi colon (;) i'm trying to split every string in that listbox (lstArchivo) that has the semicolon. The problem i'm having is that when i display the new splitted list in listbox1 the output i get is String[] Array in every item. Is it better to split every string reading from textfile directly or reading from listbox?
string[] strFields;
string strLine;
char[] charDelimiter = { ';' };
foreach(string item in lstArchivo.Items)
{
strLine = lstArchivo.Items.ToString();
strFields = strLine.Split(charDelimiter);
listBox1.Items.Add(strFields);
}
this is the code i have
You could use code like this:
char[] charDelimiter = { ';' };
foreach(string item in lstArchivo.Items)
{
strFields = item.Split(charDelimiter);
listBox1.Items.Add(strFields[0]);
}
Note that we are splitting on "item" from your foreach loop.
I have a string that contains a first and last name and I wanted to split into two separate strings so I used this code:
string Delname = bkDel.ContactName;
string[] Deltmp = Delname.Split(' ');
string DelFirstName = Deltmp[0];
string DelLastName = Deltmp[1];
It works fine if there is a first and last name but this causes an error if the name string only contains a first name:
Index was outside the bounds of the array.
since Deltmp[1] is null.
Is there a way to check the name string so if it only contains one string then don't try and split?
You can either check on the length of the array:
if (Deltmp.Length > 1)
//Assign to vars
Or you can check if the input string contains spaces:
if (Delname.Contains(" "))
//Do split
For example:
string[] Deltmp = Delname.Split(' ');
if (Deltmp.Length > 1)
//Assign to both
else
//Assign to only one
You could do a simple check like this.
if(Delname.Split(' ').Count() > 1)
{
// Has First and Last Name
}
else
{
// Has Single Name
}
You can use Delname.Trim(' ') method to delete spaces from start and end, and then check string with Delname.Contains(" "))
What about checking the input with regular expressions? Here is a simple regex pattern, but you may need to get more sophisticated depending on your supported language requirements.
Regex reg = new Regex(#"[A-Za-z]+ [A-Za-z]+");
string Delname = bkDel.ContactName;
Delname = Delname.Trim()
if (!reg.IsMatch(Delname)){
// Don't split
return;
}
string[] Deltmp = Delname.Split(' ');
string DelFirstName = Deltmp[0];
string DelLastName = Deltmp[1];
This question already has answers here:
split a string on newlines in .NET
(17 answers)
Closed 6 years ago.
After reading a text file, I pass the information through a method that splits the string to get the required information for each field. I have gotten to the point where i split the string based on new lines, but it is beyond me why when I display the subsequent array (or list it's converted to), it only shows the first half of the first split string.
An example of how the input string looks:
ASSIGNMENT
In-Class Test 02/07/2014
In-Class Test 21/04/2013
Find my code below (the numLines variable was to simply see if it was being split into the correct number of lines as it should)
private void assignmentfinder(string brief, string id)
{
string searchcrit = "ASSIGNMENT";
string assignment = brief.Substring(brief.IndexOf(searchcrit) + searchcrit.Length);
string[] assignmentsplit;
assignmentsplit = assignment.Split('\t');
List<string> Assign = new List<string>(assignmentsplit);
listBox2.DataSource = Assign;
int numLines = assignment.Split('\n').Length;
richTextBox1.Lines=(assignmentsplit);
}
The output I get is:
In-Class Test
02/07/2014
Whereas it should show the second string split as well. Any ideas?
The problem is in the value of "brief" variable. Make sure the value you are putting in "brief" variable, actually conains "\n" and "\t".
You could use regex like this:
private void assignmentfinder(string brief, string id)
{
Regex rgxLines = new Regex(#"^(.*?)[ \t]+([0-9]{2}\/[0-9]{2}\/[0-9]{4})", RegexOptions.Multiline);
MatchCollection mLines = rgxLines.Matches(brief);
foreach (Match match in mLines)
{
richTextBox1.Text += String.Format("Test: {0}{1}Date: {2}{1}{1}",
match.Groups[1].Value,
Environment.NewLine,
match.Groups[2].Value);
}
}
Your mistake is that you split for each tab (\t). Split for the new line as you say:
private void assignmentfinder(string brief, string id)
{
string searchcrit = "ASSIGNMENT";
string assignment = brief.Substring(brief.IndexOf(searchcrit) + searchcrit.Length);
string[] assignmentSplit = assignment.Split('\n'); // splitting at new line
richTextBox1.Lines = assignmentSplit;
listBox2.DataSource = assignmentSplit.ToList();
}
I hope this helps.
EDIT: Just fixed a huge mistake
Question: Is it on purpose that the string id is never used?
You could use Linq to split on new line, then on tab, skipping the first line then aggregate into a list of string:
string brief = #"ASSIGNMENT
In-Class Test 02/07/2014
In-Class Test 21/04/2013";
List<string> theLines = new List<string>();
var lines = brief.Split('\n').Skip(1).Select (b => b.Split('\t'));
foreach (var line in lines)
{
for (int i = 0; i < line.Length; i++)
{
theLines.Add(line[i]);
}
}
I have a text-file with many lines, each line looks like this:
"string string double double" between each value is a space. I'd like to read out the first string and last double of every line and put these two values in a existing list. That is my code so far, but it doesnt really work.
private void bOpen_Click(object sender, RoutedEventArgs e)
{
bool exists = File.Exists(#"C:\Users\p2\Desktop\Liste.txt");
if (exists == true)
{
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(#"C:\Users\p2\Desktop\Liste.txt"))
{
Vgl comp = new Vgl();
comp.name = Abzahlungsdarlehenrechner.zgName;
comp.gErg = Abzahlungsdarlehenrechner.zgErg;
GlobaleDaten.VglDaten.Add(comp);
int i = 0;
string line = File.ReadLines(#"Liste.txt").Skip(0).Take(1).First();
while ((line = sr.ReadLine()) != null)
{
sb.Append((line));
listBox.Items.Add(line);
GlobaleDaten.VglDaten.Add(comp);
i++;
}
}
}
I have already read this, but it didnt help How do I read specific value[...]
You can try Linq:
var source = File
.ReadLines(#"C:\Users\p2\Desktop\Liste.txt")
.Select(line => line.Split(' '))
.Select(items => new Vgl() {
name = items[0],
gErg = double.Parse(items[3])
});
// If you want to add into existing list
GlobaleDaten.VglDaten.AddRange(source);
// If you want to create a new list
//List<Vgl> list = source.ToList();
how about
List<Vgl> Result = File.ReadLines(#"C:\Users\p2\Desktop\Liste.txt")
.Select(x => new Vgl()
{
name = x.Split(' ').First(),
gErg = decimal.Parse(x.Split(' ').Last(), NumberStyles.AllowCurrencySymbol)
})
.ToList();
I would avoid storing money within doulbe values because this could lead to rounding issues. Use decimal instead. Examples here: Is a double really unsuitable for money?
You can use:
string[] splitBySpace = line.Split(' ');
string first = splitBySpace.ElementAt(0);
decimal last = Convert.ToDecimal(splitBySpace.ElementAt(splitBySpace.Length - 1));
Edit : To Handle Currency symbol:
string[] splitBySpace = line.Split(' ');
string pattern = #"[^0-9\.\,]+";
string first = splitBySpace.ElementAt(0);
string last = (new Regex(pattern)).Split(splitBySpace.ElementAt(splitBySpace.Length - 1))
.FirstOrDefault();
decimal lastDecimal;
bool success = decimal.TryParse(last, out lastDecimal);
I agree with #Dmitry and fubo, if you are looking for alternatives, you could try this.
var source = File
.ReadLines(#"C:\Users\p2\Desktop\Liste.txt")
.Select(line =>
{
var splits = line.Split(' '));
return new Vgl()
{
name = splits[0],
gErg = double.Parse(splits[3])
};
}
use string.split using space as the delimiter on line to the string into an array with each value. Then just access the first and last array element. Of course, if you aren't absolutely certain that each line contains exactly 4 values, you may want to inspect the length of the array to ensure there are at least 4 values.
reference on using split:
https://msdn.microsoft.com/en-us/library/ms228388.aspx
Read the whole file as a string.
Split the string in a foreach loop using \r\n as a row separator. Add each row to a list of strings.
Iterate through that list and split again each record in another loop using space as field separator and put them into another list of strings.
Now you have all the four fields containig one row. Now just use First and Last methods to get the first word and the last number.
This is a program that reads in a CSV file, adds the values to a dictionary class and then analyses a string in a textbox to see if any of the words match the dictionary entry. It will replace abbreviations (LOL, ROFL etc) into their real words. It matches strings by splitting the inputted text into individual words.
public void btnanalyze_Click(object sender, EventArgs e)
{
var abbrev = new Dictionary<string, string>();
using (StreamReader reader = new StreamReader("C:/Users/Jordan Moffat/Desktop/coursework/textwords0.csv"))
{
string line;
string[] row;
while ((line = reader.ReadLine()) != null)
{
row = line.Split(',');
abbrev.Add(row[0], row[1]);
Console.WriteLine(abbrev);
}
}
string twitterinput;
twitterinput = "";
// string output;
twitterinput = txtInput.Text;
{
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
string text = twitterinput;
string[] words = twitterinput.Split(delimiterChars);
string merge;
foreach (string s in words)
{
if (abbrev.ContainsKey(s))
{
string value = abbrev[s];
merge = string.Join(" ", value);
}
if (!abbrev.ContainsKey(s))
{
string not = s;
merge = string.Join(" ", not);
}
;
MessageBox.Show(merge);
}
The problem so far is that the final string is outputted into a text box, but only prints the last word as it overwrites. This is a University assignment, so I'm looking for a push in the correct direction as opposed to an actual answer. Many thanks!
string.Join() takes a collection of strings, concatenates them together and returns the result. But in your case, the collection contains only one item: value, or not.
To make your code work, you could use something like:
merge = string.Join(" ", merge, value);
But because of the way strings work, this will be quite slow, so you should use StringBuilder instead.
This is the problem:
string not = s;
merge = string.Join(" ", not);
You are just joining a single element (the latest) with a space delimiter, thus overwriting what you previously put into merge.
If you want to stick with string you need to use Concat to append the new word onto the output, though this will be slow as you are recreating the string each time. It will be more efficient to use StringBuilder to create the output.
If your assignment requires that you use Join to build up the output, then you'll need to replace the target words in the words array as you loop over them. However, for that you'll need to use some other looping mechanism than foreach as that doesn't let you modify the array you're looping over.
Better to User StringBuilder Class for such purpose
http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx