TrimEnd not erase last spaces - c#
I want to copy selected rows from my data grid view to clipboard
And it's work perfect, just one thing: I not success to remove last 3 spaces from the string.
(I also try: clipboard.Remove(clipboard.Length - 3) and clipboard.Trim(), but both not working too)
My function:
private void menuCopyClipboard_wholeRow_Click(object sender, EventArgs e)
{
#region calculate spaces
int[] spaces = new int[8]; // I have 8 columns in the data grid view
for (int i = 0; i < 8; i++)
spaces[i] = 0;
foreach (DataGridViewRow dgvr in datagridview1.SelectedRows)
foreach (DataGridViewColumn dgvc in datagridview1.Columns)
{
int cellLength = datagridview1.Rows[dgvr.Index].Cells[dgvc.Index].FormattedValue.ToString().Length;
if (spaces[dgvc.Index] < cellLength)
spaces[dgvc.Index] = cellLength;
}
#endregion
string clipboard = "";
foreach (DataGridViewRow dgvr in datagridview1.SelectedRows)
{
foreach (DataGridViewColumn dgvc in datagridview1.Columns)
clipboard += String.Format("{0, -" + spaces[dgvc.Index] + "} ", // 3 spaces between columns
datagridview1.Rows[dgvr.Index].Cells[dgvc.Index].FormattedValue.ToString());
if (dgvr.Index != 0 && datagridview1.SelectedRows.Count > 1) clipboard += "\n"; // to not add enter after last line nor copy one line
}
clipboard.TrimEnd(); // <-- doens't erase spaces
Clipboard.SetText(clipboard);
}
The problem: The spaces not erased, as you can see in the picture below:
(The question: what wrong? why the spaces are not erased?)
Strings are immutable.
That beeing said, a string manipulating method like TrimEnd() will always return a new string.
So doing this:
clipboard = clipboard.Trim();
will just fix your problem.
If you also need to remove the \n you can use this:
char[] trimChars = new char[]{' ','\n'};
clipboard = clipboard.TrimEnd(trimChars);
TrimEnd() removes all trailing occurrences of a set of characters specified in an array from the current String object, and returns the resultant string, so you should receive the converted string.
char[] charsToTrim = {' '};
clipboard = clipboard.TrimEnd(charsToTrim);
In this line
if (dgvr.Index != 0 && datagridview1.SelectedRows.Count > 1) clipboard += "\n"; // to not add enter after last line nor copy one line
You're adding a "\n" at the ending of the string, that's prevent the Trim to work try trimming before adding the "\n".
if (dgvr.Index != 0 && datagridview1.SelectedRows.Count > 1) clipboard = clipboard.Trim() + "\n"; // to not add enter after last line nor copy one line
else clipboard = clipboard.Trim();
Use this
clipboard.Trim();
Instead of :
clipboard.TrimEnd();
Related
Wrap string without cutting words for thermal printer
I am trying to print a string by thermal printer, but the problem is that paper accept only 32 charcters in a line and than break rest text to another line, by this last character always cut into two parts and string is hard to understand. Example: string PrintStr = "01-(200),02-(200),03-(200),04-(200),05-(200)"; Current output: 01-(200),02-(200),03-(200),04-(20 # <- 200 is broken into 20 and 0 0),05-(200) Better output: 01-(200),02-(200),03-(200), # Split on comma, numbers are preserved 04-(200),05-(200) I also use a Linq mehtod to break line after 32th character but the last character is cutting. I just want after last Comma "," in first 32 characters a new line will be add by that my string will break in readable text. I am sharing my code. Thanks in advance for help.. Input: var PrintStr = "01-(200),02-(200),03-(200),04-(200),05-(200),06-(200),07-(200),08-(200),09- (200),10-(200),11-(200),12-(200),13-(200),14-(200),15- (200),16-(200),17-(200),18-(200),19-(200),20-(200),21-(200),22-(200),23-(200),24-(200),25-(200),26- (200),27-(200),28-(200),29-(200),30-(200),31-( 200),32-(200),33-(200),34-(200),35-(200),36-(200),37-(200),38-(200),39-(200),40-(200),41-(200),42- (200),43-(200),44-(200),45-(200),46-(200),47-(200),48- (200),49-(200),50-(200),51-(200),52-(200),53-(200),54-(200),55-(200),56-(200),57-(200),58-(200),59- (200),60-(200),61-(200),62-(200),63-(200),64- (200),65-(200),66-(200),67-(200),A1111-(200)" Code (my attept): var AdjustPrintStr = string.Join(Environment.NewLine, PrintStr .ToLookup(c => k++ / 32) .Select(e => new String(e.ToArray()))); Output (current, unwanted): 01-(200),02-(200 ),03-(200),04-(200),05-(200),06- (200),07-(200),08-(200),09-(200) ,10-(200),11-(200),12-(200),13-( 200),14-(200),15-(200),16-(200), 17-(200),18-(200),19-(200),20-(2 00),21-(200),22-(200),23-(200),2 4-(200),25-(200),26-(200),27-(20 0),28-(200),29-(200),30-(200),31 -(200),32-(200),33-(200),34-(200 ),35-(200),36-(200),37-(200),38- (200),39-(200),40-(200),41-(200) ,42-(200),43-(200),44-(200),45-( 200),46-(200),47-(200),48-(200), 49-(200),50-(200),51-(200),52-(2 00),53-(200),54-(200),55-(200),5 6-(200),57-(200),58-(200),59-(20 0),60-(200),61-(200),62-(200),63 -(200),64-(200),65-(200),66-(200 Note, that the last "),A1111-(200)" fragment is lost
Well, you have to implement such a routine (split text at at characters ensuring at most maxWidth characters in each line) manually; it's not that difficult: public static IEnumerable<string> MySplit(string text, int maxWidth, params char[] at) { if (null == text) throw new ArgumentNullException(nameof(text)); else if (maxWidth <= 0) throw new ArgumentOutOfRangeException(nameof(maxWidth)); else if (null == at) throw new ArgumentNullException(nameof(at)); int startIndex = 0; int bestIndex = -1; for (int i = 0; i < text.Length; ++ i) { if ((i - startIndex) > maxWidth) { if (bestIndex < 0) bestIndex = i - 1; yield return text.Substring(startIndex, bestIndex - startIndex + 1); startIndex = bestIndex += 1; bestIndex = -1; } if (at.Contains(text[i])) bestIndex = i; } yield return text.Substring(startIndex); } Now, let's print out the source string: string PrintStr = #"01-(200),02-(200),03-(200),04-(200),05-(200),06-(200),07-(200),08-(200),09- (200),10-(200),11-(200),12-(200),13-(200),14-(200),15- (200),16-(200),17-(200),18-(200),19-(200),20-(200),21-(200),22-(200),23-(200),24-(200),25-(200),26- (200),27-(200),28-(200),29-(200),30-(200),31-( 200),32-(200),33-(200),34-(200),35-(200),36-(200),37-(200),38-(200),39-(200),40-(200),41-(200),42- (200),43-(200),44-(200),45-(200),46-(200),47-(200),48- (200),49-(200),50-(200),51-(200),52-(200),53-(200),54-(200),55-(200),56-(200),57-(200),58-(200),59- (200),60-(200),61-(200),62-(200),63-(200),64- (200),65-(200),66-(200),67-(200),A1111-(200)"; It seems, you should preprocess it in order to remove all new lines, tabulations, spaces etc. and only then split it: // Let's remove all white spaces (new lines, tabulations, spaces) PrintStr = Regex.Replace(PrintStr, #"\s+", ""); // split on comma ',' while ensuring each lines <= 32 characters var result = string.Join(Environment.NewLine, MySplit(PrintStr, 32, ',')); Console.Write(result); Outcome: 01-(200),02-(200),03-(200), 04-(200),05-(200),06-(200), 07-(200),08-(200),09-(200), 10-(200),11-(200),12-(200), 13-(200),14-(200),15-(200), 16-(200),17-(200),18-(200), 19-(200),20-(200),21-(200), 22-(200),23-(200),24-(200), 25-(200),26-(200),27-(200), 28-(200),29-(200),30-(200), 31-(200),32-(200),33-(200), 34-(200),35-(200),36-(200), 37-(200),38-(200),39-(200), 40-(200),41-(200),42-(200), 43-(200),44-(200),45-(200), 46-(200),47-(200),48-(200), 49-(200),50-(200),51-(200), 52-(200),53-(200),54-(200), 55-(200),56-(200),57-(200), 58-(200),59-(200),60-(200), 61-(200),62-(200),63-(200), 64-(200),65-(200),66-(200), 67-(200),A1111-(200) Hope, it's the very picture you want to see after printing
How to remove lines one by one in Richtextbox C#
I use this code to delete lines one by one in richtextbox, but still leaving an empty line (whitespace). var text = "";//Holds the text of current line being looped. var startindex = 0;//The position where selection starts. var endindex = 0;//The length of selection. for (int i = 0; i < richtextbox1.Lines.Length; i++)//Loops through each line of text in RichTextBox { text = richtextbox1.Lines[i]; //Stores current line of text. startindex = richtextbox1.GetFirstCharIndexFromLine(i); endindex = text.Length; richtextbox1.Select(startindex, endindex); MessageBox.Show(richtextbox1.SelectedText); richtextbox1.SelectedText = ""; } How do I delete lines one by one without empty lines (whitespace)?
// Gets the number of newline characters in your rich text box var numberOfNewLines = richTextBox1.Text.Count(r => r == '\n'); for (var i = 0; i < numberOfNewLines; i++) { // Finds the first occurance of the newline character var newlineCharacterIndex = richTextBox1.Text.IndexOf('\n') + 1; // Replaces the rich textbox text with everything but the above line richTextBox1.Text = richTextBox1.Text.Substring(newlineCharacterIndex); MessageBox.Show("OK!"); } // Removes the final line. richTextBox1.Text = string.Empty; I think you were on the right track, but the way you were doing it was just removing the contents of the line and not the line itself.
C# - split a RichTextBox line in two based on the caret position
I've got a RichTextBox, here referred to as box. string currentline = box.Lines[box.GetLineFromCharIndex(box.SelectionStart)]; That line there fetches the line the caret is in. It works excellently. However, I have a need to get two strings from this. The first is everything on that line UP to the caret, and the second is everything on that line AFTER it. For instance, if the line is How is you|r day going?, with | representing the caret, I would get How is you and r day going?, separately. I wrote this monstrosity, which works: string allbefore = box.Text.Substring(0, box.SelectionStart); string allafter = box.Text.Substring(box.SelectionStart, box.Text.Length - box.SelectionStart); string linebefore = ""; for (int i = 0; i < allbefore.Length; i++) { linebefore += allbefore[i]; if (allbefore[i] == '\n') linebefore = ""; } string lineafter = ""; for (int i = 0; i < allafter.Length; i++) { if (allafter[i] == '\n') break; else lineafter += allafter[i]; } It gives me the result I want, but involves looping through EVERY character in the entire box, which just hurts. Is there an easy way to do this I'm just missing? Thanks.
This might do the trick for you string currentline = box.Lines[box.GetLineFromCharIndex(box.SelectionStart)]; var listOfStrings = new List<string>(); string[] splitedBox = currentline.Split('|'); foreach(string sp in splitedBox) { string[] lineleft = sp.Split('\n'); listOfStrings.Add(lineleft[lineleft.Count() - 1]); } In the first approach we are splitting the line by char | than finding if we have any \n if it exsist we are taking the values accordingly Another approach could be string box = "How is \n you|r day \n going?"; bool alllinesremoved = true; while(alllinesremoved) { if(box.Contains('\n')) { if(box.IndexOf('\n') > box.IndexOf('|')) { box = box.Remove(box.IndexOf('\n'), (box.Length - box.IndexOf('\n'))); } else { box = box.Remove(0, box.IndexOf('\n') + 1); } } else { alllinesremoved = false; } } string[] splitedBox = box.Split('|'); in the second approach we are removing the characters before and after the \n and then splitting the string. I think the second one seems more good to me.
Have you tried using line.split? Not sure if this is what you want.
Store the position of \n using indexOf and, if >= 0, that is, the string contains it, use substring and assign the value otherwise. string allbefore = box.Text.Substring(0, box.SelectionStart); string allafter = box.Text.Substring(box.SelectionStart, box.Text.Length - box.SelectionStart); int newLinePos = allBefore.lastIndexOf("\n"); string lineBefore = ((newLinePos >= 0) ? (allBefore.substring(newLinePos + 1)) : (allBefore)); newLinePos = allafter.indexOf("\n"); string lineAfter = ((newLinePost >= 0) ? (allAfter.substring(0, newLinePos)) : (allAfter));
Issue with .NET String.Split
I'm attempting to parse a text file containing data that is being used on a remote FTP server. The data is delimited by an equals sign (=) and I'm attempting to load each row in to two columns in a DataGridView. The code I have written works fine except for when an equals character is thrown into the second column's value. When this happens, regardless of specifying the maximum count as being 2. I'd prefer not to change the delimiter if possible. Here is the code that is being problematic: dataGrid_FileContents.Rows.Clear(); char delimiter = '='; StreamReader fileReader = new StreamReader(fileLocation); String fileData = fileReader.ReadToEnd(); String[] rows = fileData.Split("\n".ToCharArray()); for(int i = 0; i < rows.Length; i++) { String str = rows[i]; String[] items = str.Split(new char[] { delimiter }, 1, StringSplitOptions.RemoveEmptyEntries); if (items.Length == 2) { dataGrid_FileContents.Rows.Add(items[0], items[1]); } } fileReader.Close(); And an example of the file being loaded: boats=123 cats=234-f cars==1 It works as intended for the first two rows and then ignores the last row as it ends up creating a String[] with 1 element and two String[]s with zero elements.
Try the following. It will capture the value before and after the first '=', correctly parsing the cars==1 scenario. String[] items = str.Split(new char[] { delimiter }, 2, stringSplitOptions.None);
A different solution, if you want everything after the first equals then you could approach this problem using string.IndexOf for(int i = 0; i < rows.Length; i++) { String str = rows[i]; int pos = str.IndexOf(delimiter); if (pos != -1) { string first = str.Substring(0, pos-1); string second = str.Substring(pos + 1); dataGrid_FileContents.Rows.Add(first, second); } }
Just read all items delimeted by '=' in row. Then iterate over items, and check, that item not empty, than use this prepared data to write here illustrated snippet http://dotnetfiddle.net/msVho2 and your snippet can be transformed to something like bellow dataGrid_FileContents.Rows.Clear(); char delimiter = '='; using(StreamReader fileReader = new StreamReader(fileLocation)) { string[] data = new string[2]; while(true) { string row = fileReader.ReadLine(); if(row == null) break; string[] items = row.Split(delimiter); int data_index = 0; foreach(string item in items) { if(data_index >= data.Length) { //TODO: log warning break; } if(!string.IsNullOrWhiteSpace(item)) { data[data_index++] = item; } } if(data_index < data.Length) { //TODO: log error, only 1 item in row continue; } dataGrid_FileContents.Rows.Add(data[0], data[1]); } }
Add to string until hits length (noobie C# guy)
I am trying to read a text file, break it into a string array, and then compile new strings out of the words, but I don't want it to exceed 120 characters in length. What I am doing with is making it write PML to create a macro for some software I use, and the text can't exceed 120 characters. To take it even further I need to wrap the 120 characters or less (to the nearest word), string with "BTEXT |the string here|" which is the command. Here is the code: static void Main(string[] args) { int BIGSTRINGLEN = 120; string readit = File.ReadAllText("C:\\stringtest.txt"); string finish = readit.Replace("\r\n", " ").Replace("\t", ""); string[] seeit = finish.Split(' '); StringBuilder builder = new StringBuilder(BIGSTRINGLEN); foreach(string word in seeit) { while (builder.Length + " " + word.Length <= BIGSTRINGLEN) { builder.Append(word) } } }
Try using an if instead of the while as you will continually append the same word if not!!
Rather than read the entire file into memory, you can read it a line at a time. That will reduce your memory requirements and also prevent you having to replace the newlines. StringBuilder builder = new StringBuilder(BIGSTRINGLEN); foreach (var line in File.ReadLines(filename)) { // clean up the line. // Do you really want to replace tabs with nothing? // if you want to treat tabs like spaces, change the call to Split // and include '\t' in the character array. string finish = line.Replace("\t", string.Empty); string[] seeit = finish.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries); foreach (string word in seeit) { if ((builder.Length + word.Length + 1 <= BIGSTRINGLEN) { if (builder.Length != 0) builder.Append(' '); builder.Append(word); } else { // output line Console.WriteLine(builder.ToString()); // and reset the builder builder.Length = 0; } } } // and write the last line if (builder.Length > 0) Console.WriteLine(builder.ToString()); That code is going to fail if a word is longer than BIGSTRINGLEN. Long words will end up outputting a blank line. I think you can figure out how to handle that case if it becomes a problem.
Matthew Moon is right - your while loop is not going to work as currently placed. But that aside, you have some problems in this line while (builder.Length + " " + word.Length <= BIGSTRINGLEN) builder.Length and word.Length are integers - the number of characters in each word. " " is not an integer, it's a string. You can't correctly add 10 + " " + 5. You probably want while (builder.Length + (" ").Length + word.Length <= BIGSTRINGLEN) // or while (builder.Length + 1 + word.Length <= BIGSTRINGLEN)