Trim textbox text after 20 characters used and spaces if contains spaces - c#

I have a WinFormApp with 2 txtboxes (LongName and ShortName) with a Button.
When txt is entered in the LongName txtbox, I want to press the button to shorten all txt inside LongName txtbox to the first 20 characters imput and to remove any spaces within' the txtbox then display the results in the ShortName txtbox. I'm having a real hard time trying to get this correct. I've tried a number of ways to try but ultimately can't seem to get it right. Here is example code:
private void btnGetSN_Click(object sender, EventArgs e)
{
Regex space = new Regex(#" ");
MatchCollection spacematch = space.Matches(txtLongName.Text);
if (txtLongName.Text.Length > 20)
{
string toTrim = txtLongName.Text;
toTrim = toTrim.Trim();
txtShortName.Text = ("'" + toTrim.ToString() + "'");
}
if (spacematch.Count > 0)
{
txtLongName.Text.Replace(" ", "");
}
}//closes method
I've been able to limit the txtbox to only 20 characters in the properties but I would like to setup a If variable to allow more customization.
Am I on the right track?
No errors in the code but when executing the button, nothing happens. Any help is appreciated.

string.Replace() doesn't update the string itself, but rather returns a new string that is modified.
private void btnGetSN_Click(object sender, EventArgs e)
{
// remove space from txtLongName
txtLongName.Text = txtLongName.Text.Replace(" ", string.Empty);
// take only the first 20characters from txtLongName
txtShortName.Text = txtLongName.Text.Substring(0, Math.Min(txtLongName.Text.Length, 20));
}
EDIT: Previous code will remove space from txtLongName. If that is not intended, use this instead :
private void btnGetSN_Click(object sender, EventArgs e)
{
// remove space from txtLongName
var name = txtLongName.Text.Replace(" ", string.Empty);
// take only the first 20characters from txtLongName
txtShortName.Text = name.Substring(0, Math.Min(name.Length, 20));
}

Looks like you need to write differently
private void button1_Click(object sender, EventArgs e)
{
var shortName = txtLongName.Text.Trim().Replace(" ", "");
var maxLength = (shortName.Length > 20) ? 20 : shortName.Length;
if(txtLongName.Text.Trim().Length > 0)
txtShortName.Text = shortName.Substring(0, maxLength);
}

Related

How to use a MessageBox in a function

I am trying to get function to take in two strings and show message box:
public void Myfunction (string str1, string str2)
{
MessageBox.Show("your message was " + str1 + Environment.NewLine + str2);
}
private void Btn_Display_Click(object sender, RoutedEventArgs e)
{
string today;
today = DateTime.Now.ToString("dd/MM/yyyy");
myfunction(TextBox_Msg.Text, today);
}
It's not clear what's going on, say, what myfunction is supposed to do? Functions compute values.
I suggest showing message in one go:
private void Btn_Display_Click(object sender, RoutedEventArgs e) {
// Show message - MessageBox.Show
// of several lines - string.Join(Environment.NewLine
// 1st line "your message was" + TextBox_Msg.Text
// 2nd line DateTime.Now in "dd/MM/yyyy" format
MessageBox.Show(string.Join(Environment.NewLine,
$"your message was {TextBox_Msg.Text}",
DateTime.Now.ToString("dd/MM/yyyy")));
}
If you insist on extracting method then, let's first rename it - ShowMessageLines:
// Let's show arbitrary many lines (whe only 2?)
// Let's accept all types (not necessary strings)
public static void ShowMessageLines(params object[] lines) {
// public method - input arguments validation
if (null == lines)
throw new ArgumentNullException(nameof(lines));
// Combine all lines into textToShow
// First line must have a prefix - "your message was "
string textToShow = string.Join(Environment.NewLine, lines
.Select((text, index) => index == 0
? $"your message was {text}"
: text?.ToString()));
MessageBox.Show(textToShow);
}
...
private void Btn_Display_Click(object sender, RoutedEventArgs e) {
ShowMessageLines(
TextBox_Msg.Text,
DateTime.Now.ToString("dd/MM/yyyy"));
}

Need to sort words in an array using a separate method

Question:
Write a program named SortWords that includes a method that accepts any number of words and sorts them in alphabetical order. Demonstrate that the program works correctly when the method is called with one, two, five, or ten words.
What I have thus far:
private void button1_Click(object sender, EventArgs e)
{
String[] outWords = new string[20];
outWords[0] = textbox1.Text;
outWords[1] = textBox2.Text;
outWords[2] = textBox3.Text;
outWords[3] = textBox4.Text;
outWords[4] = textBox5.Text;
outWords[5] = textBox6.Text;
outWords[6] = textBox7.Text;
outWords[7] = textBox8.Text;
outWords[8] = textBox9.Text;
outWords[9] = textBox10.Text;
sortAndPrint(outWords[11]);
}
private void sortAndPrint(params string[] newWords)
{
Array.Sort(newWords);
label1.Text = newWords[0];
label2.Text = newWords[1];
label3.Text = newWords[2];
label4.Text = newWords[3];
label5.Text = newWords[4];
label6.Text = newWords[5];
label7.Text = newWords[6];
label8.Text = newWords[7];
label9.Text = newWords[8];
label10.Text = newWords[9];
}
My issues here is that I either don't get anything in my label boxes or I get errors thrown from can't convert a string into string[] or System.IndexOutOfRangeException. I'm sure im doing something completely wrong here.
Try this :
private void button1_Click(object sender, EventArgs e)
{
string[] outWords = new string[10];
outWords[0] = textbox1.Text;
outWords[1] = textBox2.Text;
outWords[2] = textBox3.Text;
outWords[3] = textBox4.Text;
outWords[4] = textBox5.Text;
outWords[5] = textBox6.Text;
outWords[6] = textBox7.Text;
outWords[7] = textBox8.Text;
outWords[8] = textBox9.Text;
outWords[9] = textBox10.Text;
sortAndPrint(outWords);
}
private void sortAndPrint(string[] newWords)
{
Array.Sort(newWords);
label1.Text = newWords[0];
label2.Text = newWords[1];
label3.Text = newWords[2];
label4.Text = newWords[3];
label5.Text = newWords[4];
label6.Text = newWords[5];
label7.Text = newWords[6];
label8.Text = newWords[7];
label9.Text = newWords[8];
label10.Text = newWords[9];
}
Summary
Pass whole array sortAndPrint(outWords); not single element.
Take array length only what you need. string[] outWords = new string[10];
Please check this question for the use of params. You need to pass values when you user param but if you need to pass variable, you have to remove params.
Example of params
private void button1_Click(object sender, EventArgs e)
{
sortAndPrint("one","two","three","four","five");
}
private void sortAndPrint(params string[] newWords)
{
Array.Sort(newWords);
label1.Text = newWords[0];
label2.Text = newWords[1];
label3.Text = newWords[2];
label4.Text = newWords[3];
label5.Text = newWords[4];
}
sortAndPrint(outWords[11]);
will pass a single string (as an array) to sortAndPrint, so when you call
label2.Text = newWords[1];
you get an out of bounds exception. Try just
sortAndPrint(outWords);
to pass the entire array. Also note that empty slots in the array wil get sorted before other strings, so you need to come up with a way to get rid of the blank/null string.
Or, if the intent is to demonstrate how to use params, you could do something like:
sortAndPrint(textbox1.Text,
textbox2.Text,
textbox3.Text,
textbox4.Text,
textbox5.Text);
But you need to check the bounds of the array in sortAndPrint, rather than just assuming the array has a size of at least 10.
If you read the instructions carefully, you have this requirement:
...includes a method that accepts any number of words...
You accomplish this by using the params keyword along with a string[].
...and sorts them in alphabetical order.
This part you doing with Array.Sort(newWords);
Demonstrate that the program works correctly when the method is called with one, two, five, or ten words
This part you're not doing - you're assuming in your code that the input array will have 10 items, when instead you should check to see how many items it has before outputting the results.
Since the array size cannot be determined by the method, then it cannot make any assumption that there will be enough labels on the form to populate with the results. Given this, we could use a MessageBox to show the results instead, and we can use String.Join to join all the items in the array with an Environment.NewLine character in order to show the sorted words in different lines:
private void SortAndPrint(params string[] newWords)
{
Array.Sort(newWords);
MessageBox.Show(string.Join(Environment.NewLine, newWords));
}
Now, we can demonstrate the use of this function by passing in different numbers of arguments to it.
First, just so we're on the same page, I have this code in the Form_Load method that adds 10 textboxes to the form, all with the tag "input":
private void Form1_Load(object sender, EventArgs e)
{
var stdHeight = 20;
var stdWidth = 100;
var stdPad = 10;
var count = 10;
for (int i = 0; i < count; i++)
{
var textBox = new TextBox
{
Name = "textBox" + (i + 1),
Left = stdPad,
Width = stdWidth,
Height = stdHeight,
Top = (stdHeight + stdPad) * i + stdPad,
Tag = "input"
};
Controls.Add(textBox);
}
}
Now, in our button click event, we can search for all controls on the form who have the Tag == "input" and whose .Text property is not empty, and we can pass these Text values to our method both as a single array OR as individual items:
private void button1_Click(object sender, EventArgs e)
{
// Select all textbox Text fields that have some value
var words = Controls.Cast<Control>()
.Where(t => t.Tag == "input" && !string.IsNullOrWhiteSpace(t.Text))
.Select(t => t.Text)
.ToArray();
// Pass all the words in a single array to our method
SortAndPrint(words);
// We can also demonstrate this by passing individual words
// Pass one word if we can
if (words.Length > 0)
{
SortAndPrint(words[0]);
}
// Pass two words if we can
if (words.Length > 1)
{
SortAndPrint(words[0], words[1]);
}
// Pass five words if we can
if (words.Length > 4)
{
SortAndPrint(words[0], words[1], words[2], words[3], words[4]);
}
// Pass ten words if we can
if (words.Length > 9)
{
SortAndPrint(words[0], words[1], words[2], words[3], words[4],
words[5], words[6], words[7], words[8], words[9]);
}
}

C# insert text after each occurence of a text string using wildcards [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Solved:
This solution has been solved. I was modding a game and am creating a C# windows form to easily manipulate large quantities of repeating data, or expressions, and quickly insert mass changes to a file, or files. I was stuck on identifying a regular expression with Regex in my data files and inserting a text box field of data right after the expression I identified. The expression I have works in the regex editor, thanks to #Kris, but when I deployed it into my program, nothing happened. I apologize for not having my thoughts in order, I will be sure to be more clear next time I use SO.
Below is the data I wanted to manipulate, followed by the working code I was able to fix myself with pointers from #Kris and #Rufus L. Again, I needed to search for particular data strings and insert a new string underneath the data property in every occurrence in the file. Hope this helps someone.
The data properties text looks like this:
1234 = {
workers = {
culture = dudes
religion = awesome
size = 37800
}
professionals = {
culture = dudes
religion = awesome
size = 6000
}
leaders = {
culture = dudes
religion = awesome
size = 500
}
}
1235 = {
workers = {
culture = dudes
religion = awesome
size = 37800
}
professionals = {
culture = dudes
religion = awesome
size = 6000
}
leaders = {
culture = dudes
religion = awesome
size = 500
}
}
I only want to insert text into the parent #### = {} property that holds the child = {} property fields. IE, I want to insert textBox2.Text in a new line under 1234 = {
I have the regex expression linked on here, thanks to #Kris.
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
static string[] files;
static int curNum = 0;
static string[] txtFiles;
static string[] provinces;
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
System.IO.File.WriteAllText(pathText.Text + txtFiles[curNum], richTextBox1.Text);
}
private void prevButton_Click(object sender, EventArgs e) {
if(curNum > 0)
curNum--;
richTextBox1.Text = System.IO.File.ReadAllText(pathText.Text + txtFiles[curNum]);
filenameLabel.Text = txtFiles[curNum];
}
private void loadButton_Click(object sender, EventArgs e) {
curNum = 0;
txtFiles = GetFileNames(pathText.Text, "*.txt");
richTextBox1.Text = System.IO.File.ReadAllText(pathText.Text + txtFiles[curNum]);
filenameLabel.Text = txtFiles[curNum];
}
static string[] GetFileNames(string path, string filter) {
files = Directory.GetFiles(path, filter);
for (int i = 0; i < files.Length; i++)
files[i] = Path.GetFileName(files[i]);
return files;
}
private void nextButton_Click(object sender, EventArgs e) {
if(curNum < txtFiles.Length)
curNum++;
richTextBox1.Text = System.IO.File.ReadAllText(pathText.Text + txtFiles[curNum]);
filenameLabel.Text = txtFiles[curNum];
}
private void appendButton_Click(object sender, EventArgs e)
{
provinces = Regex.Matches(richTextBox1.Text, #"\d+(.*?){")
.Cast<Match>()
.Select(m => m.Value)
.ToArray();
for (int i = 0; i < provinces.Length; i++)
{
richTextBox1.Text = richTextBox1.Text.Replace(provinces[i], provinces[i] + System.Environment.NewLine + " " + textBox2.Text);
}
}
}
}
Use regex
\d+(.*?){
tested here
Another way to do it would be to insert the text at the end of each block, by searching for two } characters separated by 0 or more whitespace characters. The regex for this would look like:
Regex.Matches(searchString, "}\\s}");
In either case, when inserting the strings we should start from the last match (at the end of the string) and move backwards towards the beginning, because each insert will change the string length and therefore impact the index at which we want to do the insertion.
For example:
/// <summary>
/// Returns a string with newText inserted into parentText
/// </summary>
/// <param name="newText">The new text to insert</param>
/// <param name="parentText">The parent text to insert into</param>
/// <returns>The parent string with the newText inserted</returns>
private string GetInsertedText(string newText, string parentText)
{
var newParentText = parentText;
var matches = Regex.Matches(newParentText, "}\\s}");
// Replace from the last occurrence, since each insert will
// change the length of our string and alter the insert location
for(int index = matches.Count - 1; index >= 0; index--)
{
var match = matches[index];
newParentText = newParentText.Substring(0, match.Index + 1) +
Environment.NewLine + newText +
newParentText.Substring(match.Index + 1);
}
return newParentText;
}
You also might want to create a method that adds 4 spaces to the beginning of each line of the textBox1.Text so that it has a proper indent after it's inserted. For example:
private string GetIndentedText(string originalText, string indentText = " ")
{
return $"{indentText}{originalText}".Replace("\n", $"\n{indentText}").TrimEnd();
}
The usage of this would look something like:
private void button1_Click(object sender, EventArgs e)
{
// Check for any text requirements here (like it should contain
// an open brace, an equals sign, end with a close brace, etc.)
if (textBox1.Text.Length > 0)
{
// Insert the new (indented) text into our RichTextBox
richTextBox1.Text = GetInsertedText(GetIndentedText(textBox1.Text),
richTextBox1.Text);
// Clear the input textbox
textBox1.Text = "";
}
}

Seperate a label into 2 different Textbox C#

I wanted to know how i could split this label into 2 different textboxes. Before writing here i searched google and came this far, but now both of my textboxes is showing the value 1000. The program is supposed to split the numbers between the x.
Example: Left textbox = 80 & Right textbox = 1000. What am I missing?
private void Split_btn_Click(object sender, EventArgs e)
{
string s = label1.Text;
// Split string on spaces.
// ... This will separate all the words.
string[] words = s.Split('x');
foreach (string word in words)
{
Left_txtbox.Text = word;
Right_Textbox.Text = word;
}
}
The problem is the loop. You are setting both textboxes with the same value and overwriting it with every iteration so the last values wins.
You could simply assign the values like follows:
Left_txtbox.Text = words[0];
Right_Textbox.Text = words[1];
I would add the trim() command in as well because you will end up with a space after the 80 and before the 1000.
private void button1_Click(object sender, EventArgs e)
{
string s = label1.Text;
string[] words = s.Split('x');
Left_txtbox.Text = words[0].Trim();
Right_Textbox.Text = words[1].Trim();
}
or add the split directly into the textbox assign
private void button1_Click(object sender, EventArgs e)
{
string s = label1.Text;
Left_txtbox.Text = s.Split('x')[0].Trim();
Right_Textbox.Text = s.Split('x')[1].Trim();
}
Try this instead of your foreach loop:
if (words.Length > 1)
{
Left_txtbox.Text = words[0];
Right_Textbox.Text = words[1];
}

Swapping each word in a string into a certain order

I am trying to get a string of text from one text box and put it into the next text box inverted but readable like this. "Help please" and in the next box when I click the button it should say "please Help". I have been trying everything that I can think of. Sorry very new to this. Ill attach the code
private void button1_Click(object sender, EventArgs e)
{
string converttext = txtInputBox.Text;
StringBuilder sb = new StringBuilder(converttext.Length);
for (int i = converttext.Length - 1; i >= 0; --i)
{
sb.Append(converttext[i]);
}
string reversed = sb.ToString();
txtOutputBox.Text = reversed;
}
You can split the string on space and then reverse the result and pass it to string.Join like:
string str = "Help please";
string newStr = string.Join(" ", str.Split().Reverse());
txtOutputBox.Text = String.Join(" ", txtInputBox.Text.Split().Reverse());

Categories