C# Syntax - Remove last occurrence of ';' in string from split - c#

I have a list of strings stored in an ArrayList. I want to split them by every occurrence of ';'. The problem is, whenever I try to display them using MessageBox, there's an excess space or unnecessary value that gets displayed.
Sample input (variable = a):
Arial;16 pt;None;None;None;None;None;None;FF0000;None;100;Normal;None;Normal;
Below is a line of code I used to split them:
string[] display_document = (a[0] + "").Split(';');
Code to display:
foreach (object doc_properties in display_document)
{
TextBox aa = new TextBox();
aa.Font = new Font(aa.Font.FontFamily, 9);
aa.Text = doc_properties.ToString();
aa.Location = new Point(pointX, pointY);
aa.Size = new System.Drawing.Size(80, 25);
aa.ReadOnly = true;
doc_panel.Controls.Add(aa);
doc_panel.Show();
pointY += 30;
}
The output that displays are the following:
How do I remove the last occurrence of that semicolon? I really need help fixing this. Thank you so much for all of your help.

Wouldnt It be easiest to check if the input ends with a ";" before splitting it, and if so remove the last character? Sample code:
string a = "Arial;16 pt;None;None;None;None;None;None;FF0000;None;100;Normal;None;Normal;";
if (a.EndsWith(";"))
{
a = a.Remove(a.LastIndexOf(";"));
}
//Proceed with split

Split will not print last semicolon if no space character is added and your input is a string.
I don't know why you prefer an array list (which probably is the reason of this strange behaviour) but if you could use your input as a string you could try that
string a = "Arial;16pt;None;None;None;None;None;None;FF0000;None;100;Normal;None;Normal;";
string[] display_document = a.Split(';');
foreach (object doc_properties in display_document)
{
//The rest of your code
}

Related

How to read text from file from one value to other in c#

I`m new in c#, I'm still learning that language. Now I try to make app which read text and to my data i need only specific lines. Text look like:
[HAEDING]
Some value
[HEADING]
Some other value
[HEADING]
Some other text
and continuation of this text in new line
[HEADING]
Last text
I try to write method which read text and put it into string[] by split it like this:
string[0] = Some value
string[1] = Some other value
string[2] = Some other text and continuation of this text in new line
string[3] = Last text
So I want to read line from value [HEADING] to value new line which is empty. I thought that is should write by ReadAllLines and line by line check start position on value [HEADING] and end position on empty value in new line. I try this code:
string s = "mystring";
int start = s.IndexOf("[HEADING]");
int end = s.IndexOf("\n", start);
string result = s.Substring(start, end - start);
but it's substring to all lines in my text not like loop between first [HEADING] and empty new line, second etc.
Maybe someone can help me with this?
You could try to split the string by "[HEADING]" to get the strings between these lines. Then you could join each string into a single line and trim the whitespace around the strings:
string content = #"[HEADING]
Some value
[HEADING]
Some other value
[HEADING]
Some other text
and continuation of this text in new line
[HEADING]
Last text";
var segments = content.Split(new[] { "[HEADING]"}, StringSplitOptions.RemoveEmptyEntries) // Split into multiple strings
.Select(p=>p.Replace("\r\n"," ").Replace("\r"," ").Replace("\n"," ").Trim()) // Join each single string into single line
.ToArray();
Result:
segments[0] = "Some value"
segments[1] = "Some other value"
segments[2] = "Some other text and continuation of this text in new line"
segments[3] = "Last text"
Here's a solution which avoids the substring/index checking, which could potentially be fraught with errors.
There are answers such as this one that use LINQ, but for a newcomer to the language, basic looping is an OK place to start. Also, this is not necessarily the best solution for efficiency or whatever.
This foreach loop will handle your case, and some of the "dirty" cases.
var segments = new List<string>();
bool headingChanged = false;
foreach (var line in File.ReadAllLines("somefilename.txt"))
{
// skip blank lines
if (string.IsNullOrWhitespace(line)) continue;
// detect a heading
if (line.Contains("[HEADING]")
{
headingChanged = true;
continue;
}
if (headingChanged)
{
segments.Add(line);
// this keeps us working on the same segment if there
// are more lines to be added to the segment
headingChanged = false;
}
else
{
segments[segments.Length - 1] += " ";
segments[segments.Length - 1] += line;
// you could replace the above two lines with string interpolation...
// segments[segments.Length - 1] = $"{segments[segments.Length - 1]} {line}";
}
}
In the above loop, the ReadAllLines obviates the need to check for \r and \n. Contains will handle [HEADING] no matter where it changes.
You don't need substring, you can just compare the value s == "[HEADING]".
Here's an easy to understand example:
var lines = System.IO.File.ReadAllLines(myFilePath);
var resultLines = new List<String>();
var collectedText = new List<String>();
foreach (var line in lines)
{
if (line == "[HEADING]")
{
collectedText = new List<String>();
}
else if (line != "")
{
collectedText.Add(line);
}
else //if (line == "")
{
var joinedText = String.Join(" ", collectedText);
resultLines.Add(joinedText);
}
}
return resultLines.ToArray();
the loop does this:
we go line by line
"start collecting" (create list) when we encounter with "[HEADING]" line
"collect" (add to list) line if not empty
"finish collecting" (concat and add to results list) when line is empty

Read specific values out of a text-file and put them in a list

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.

Dictionary re-adding words as new keys instead of increasing value

I am writing a program that finds every unique word in a text and prints it in a text box. I do this by printing each key in a dictionary however my dictionary is adding each word as a separate key instead of ignoring words that are already there.
The function is being called correctly and it does work it simpy prints the entire text I hand it however.
EDIT: I am reading the string from a text file then sending it to the function.
This is the input string and the output:
Output:
To be or not to that is the question Whether tis nobler in mind suffer
The slings and arrows of outrageous fortune Or take arms against a sea
troubles And by opposing end them die sleep No more sleep say we end
The heartache thousand natural shocks That flesh heir Tis consummation
public string FindUniqueWords(string text)
{
Dictionary<string, int> dictionary = new Dictionary<string, int>();
string uniqueWord = "";
text = text.Replace(",", ""); //Just cleaning up a bit
text = text.Replace(".", ""); //Just cleaning up a bit
string[] arr = text.Split(' '); //Create an array of words
foreach (string word in arr) //let's loop over the words
{
if (dictionary.ContainsKey(word)) //if it's in the dictionary
dictionary[word] = dictionary[word] + 1; //Increment the count
else
dictionary[word] = 1; //put it in the dictionary with a count 1
}
foreach (KeyValuePair<string, int> pair in dictionary) //loop through the dictionary
{
uniqueWord += (pair.Key + " ");
}
uniqueWords.Text = uniqueWord;
return ("");
}
You're reading the text with System.IO.File.ReadAllText, so text may also contain newline characters.
Replace arr = text.Split(' ') by arr = text.Split(' ', '\r', '\n') or add another replace: text = text.Replace(Environment.NewLine, " ");
Of course, by looking at arr in the debugger, you could have found out by yourself.
A shorter way: (Dont forget to use Using System.Linq)
string strInput = "TEST TEST Text 123";
var words = strInput.Split().Distinct();
foreach (var word in words )
{
Console.WriteLine(word);
}
Your code works as it's supposed to (ignoring case though). The problem almost certainly lies with showing the results in your application, or with how you are calling the FindUniqueWords method (not the complete text at once).
Also, pretty important to note here: a Dictionary<TKey, TValue> by default simply cannot contain a single key multiple times. It would defeat the whole purpose of the dictionary in the first place. It's only possible if you override the Equality comparison somewhere, which you aren't doing.
If I try your code, with the following input:
To be or not to that is is is is is is is the question
The output becomes :
To be or not to that is the question
It works like it's supposed to.

TextBox not containing "\r\n" strings

I have a program which needs to determine the number of lines in a multiline textbox to know how to process it. I am calling the TextBox.Lines.Length property, which was working. Now however, no matter how many lines of text are visible in the GUI, this value is 1, and all of the "\r\n" strings have disappeared from the TextBox.Text string. Any Ideas? My code is as following :
TextBox.MultiLine = true;
TextBox.WordWrap = true;
for (int i = 0; i < TextBox.Lines.Length - 1; i++)
//Some Code
As I said in the comment, with Multiline=True and WordWrap=True, your textbox will display a long line as multilines (Wrapped)... but actually it is one single line, and that's why your Lines.Length=1, try type in some line break yourself, and test it again. Or you can set WordWrap=False, and you will see there is only one line...
It will need to be marked as multiline, check that, you can parse like so:
string txt = TextBox1.Text;
string[] lst = txt.Split(new Char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)

Textbox displaying extra information when text file is parsed

My Goal: I want to parse a file and display it in a textbox. Here's the code (thanks to Aviral Singh).
private void Form1_Load(object sender, EventArgs e)
{
var path = #"C:\Users\Smith\Desktop\Settings.txt"; //Path to settings file.
RichTextBox rtb = new RichTextBox();
System.IO.StreamReader sis = new System.IO.StreamReader(path);
rtb.Text = sis.ReadToEnd();
sis.Close();
foreach (string line in rtb.Lines)
{
if (line.Contains("Installation Technical Manual:") == true)
{
string numbers = line.Substring(line.IndexOf("Installation Technical Manual:"));
textBox1.Text = numbers;
}
}
}
Text file looks like this:
My Problem: The textbox in my program displays entire line: Installation Technical Manual: (1234567890).
I just want the number with brackets (1234567890). to be displayed in the textbox. What changes should I make to the code to remove the words and just display numbers with brackets around it? Thanks for your help. :)
numbers = "(" + new String(numbers.Where(Char.IsDigit).ToArray()) + ")";
The problem is that IndexOf() is going to give you the starting position of the string which you're asking for the index of. Which in your example is going to be 0, so a Substring call that starts at 0 is going to return you the entire string.
What you really want to do is Substring(IndexOf("Installation Technical Manual:") + "Installation Technical Manual:".Length). That will give you whatever comes after your string.
Assuming you have ':' in your line always,
if(line.Contains(":"))
{
string numbers = line.Split(':')[1];
textBox1.Text = numbers;
}
The reason your code is not working as you have used the substring method as with one parameter, so it is used as :
public string Substring(
int startIndex
)
See: http://msdn.microsoft.com/en-us/library/hxthx5h6.aspx
And you are passing in, line.IndexOf("Installation Technical Manual:")
which will return ).
See here: http://msdn.microsoft.com/en-us/library/k8b1470s.aspx
So you are essentially saying return Substring of string Installation Technical Manual:(number) starting at 0 which basically returns the whole line.

Categories

Resources