I have text in textBox1 "Aplle,Orandge,Nuts,Cherries". There can be more words added in text box, even 30.
I need to find combination like this:
First click - I get textBox2.Text = "Aplle" AND textBox3.Text = "Orandge,Nuts,Cherries"
Second click textBox2.Text = "Aplle,Orandge" AND textBox3.Text = "Nuts,Cherries"
Third textBox2.Text = "Aplle,Orandge,Nuts" AND textBox3.Text = "Cherries"
First I understand that I need counter which count commas, if CommaCounter=1, than split after first comma, if CommaCounter=2, split after second comma, if CommaCounter=100, than split after comma 100.
Than I need splitter, I guess, but and don't understand how to really make it.
Why I need find every combination click by click because every combination will be used by another click witch makes another function.
I insert a pictures how it should look.
here is code I started, of course unfinished, incorrect...
int CommaCounter = 0;
string Part1, Part2;
string Vards = textBox1.Text;
char[] delimiterChars = { ',' };
string[] words = Vards.Split(delimiterChars);
string searchTerm = ",";
var matchQuery = from word in words
where word.ToLowerInvariant() == searchTerm.ToLowerInvariant()
select word;
int wordCount = matchQuery.Count();
foreach (string s in words)
{
textBox2.Text = Part1.ToString();
textBox3.Text = Part2.ToString();
}
First, declare a variable (let's say its name is counter) in the form. The initial value is 0. It stores how many clicks have you done.
// stores how many clicks you have done
int counter = 0;
In the button's event handler, split the text in the first textbox using a comma.
// split the first textbox using a comma
var words = textBox1.Text.Split(',');
Then compare the counter variable with the number of words in the first textbox. If counter is lesser than the number of words, split the words into the second textbox and the third textbox.
if (counter < words.Count())
{
// increase the counter
counter++;
// take n words, where n = counter
textBox2.Text = string.Join(",", words.Take(counter));
// skip n words, then take the rest (n = counter)
textBox3.Text = string.Join(",", words.Skip(counter).Take(words.Count() - counter));
}
You can get the value of the second textbox using Take() method. The Take() method get some element from the words. For the third textbox, you need to skip some words before you take the words. You skip the words using Skip() method.
Full source.
using System;
using System.Windows.Forms;
using System.Linq;
namespace Sample
{
public partial class MainForm : Form
{
// stores how many clicks you have done
int counter = 0;
public MainForm()
{
InitializeComponent();
}
void Button1Click(object sender, EventArgs e)
{
// split the first textbox using a comma
var words = textBox1.Text.Split(',');
if (counter < words.Count())
{
// increase the counter
counter++;
// take n words, where n = counter
textBox2.Text = string.Join(",", words.Take(counter));
// skip n words, then take the rest (n = counter)
textBox3.Text = string.Join(",", words.Skip(counter).Take(words.Count() - counter));
}
}
}
}
Keeping it simple:
void Button1Click(object sender, EventArgs e)
{
string divider = ",";
if(textBox2.Text == "") // first click.
{
textBox3.Text = textBox1.Text;
divider = "";
}
int pos = textBox3.Text.IndexOf(",");
if(pos > -1)
{
textBox2.Text = textBox2.Text + divider + textBox3.Text.Substring(0, pos);
textBox3.Text = textBox3.Text.Substring(pos + 1);
}
else if (textBox3.Text != "" ) // last one
{
textBox2.Text = textBox2.Text + divider + textBox3.Text;
textBox3.Text = "";
}
}
Related
I would like to know how can I add or type a number in a textbox, then this number gets saved, then add other numbers, and save them so at the end I can order them from larger to smaller and viceversa.
I got one textbox (where I type the numbers), one button (add button, that adds the typed number to the textbox2), another textbox2(where the numbers are being added simultaneously, so you can check them). There is a textbox3 (where the numbers must appear ordered from larger to smaller) and a textbox4 (where the numbers must appear ordered from smaller to larger).
Can someone help me?
Not perfect but it works. Try it.:)
//index count
int index=0;
//array declaration
string [] numbers=new string[10];
//method displaying array's content
string arrayDisplay() {
string str="";
for (int i = 0; i < numbers.Length; i++)
{
if (!(numbers[i]== "") )
{
str += numbers[i];
}
}
return str;
}
private void button1_Click(object sender, EventArgs e)
{
textBox2.Text += textBox1.Text;
index++;
if (numbers.Length >=index )
{
numbers[index] = textBox1.Text;
textBox1.Text = "";
}
//Regular sort and display
Array.Sort(numbers);
textBox3.Text = arrayDisplay();
//Reverse sort and display
Array.Reverse(numbers);
textBox4.Text = arrayDisplay();
}
Let's say I have a string like this one, left part is a word, right part is a collection of indices (single or range) used to reference furigana (phonetics) for kanjis in my word:
string myString = "子で子にならぬ時鳥,0:こ;2:こ;7-8:ほととぎす"
The pattern in detail:
word,<startIndex>(-<endIndex>):<furigana>
What would be the best way to achieve something like this (with a space in front of the kanji to mark which part is linked to the [furigana]):
子[こ]で 子[こ]にならぬ 時鳥[ほととぎす]
Edit: (thanks for your comments guys)
Here is what I wrote so far:
static void Main(string[] args)
{
string myString = "ABCDEF,1:test;3:test2";
//Split Kanjis / Indices
string[] tokens = myString.Split(',');
//Extract furigana indices
string[] indices = tokens[1].Split(';');
//Dictionnary to store furigana indices
Dictionary<string, string> furiganaIndices = new Dictionary<string, string>();
//Collect
foreach (string index in indices)
{
string[] splitIndex = index.Split(':');
furiganaIndices.Add(splitIndex[0], splitIndex[1]);
}
//Processing
string result = tokens[0] + ",";
for (int i = 0; i < tokens[0].Length; i++)
{
string currentIndex = i.ToString();
if (furiganaIndices.ContainsKey(currentIndex)) //add [furigana]
{
string currentFurigana = furiganaIndices[currentIndex].ToString();
result = result + " " + tokens[0].ElementAt(i) + string.Format("[{0}]", currentFurigana);
}
else //nothing to add
{
result = result + tokens[0].ElementAt(i);
}
}
File.AppendAllText(#"D:\test.txt", result + Environment.NewLine);
}
Result:
ABCDEF,A B[test]C D[test2]EF
I struggle to find a way to process ranged indices:
string myString = "ABCDEF,1:test;2-3:test2";
Result : ABCDEF,A B[test] CD[test2]EF
I don't have anything against manually manipulating strings per se. But given that you seem to have a regular pattern describing the inputs, it seems to me that a solution that uses regex would be more maintainable and readable. So with that in mind, here's an example program that takes that approach:
class Program
{
private const string _kinvalidFormatException = "Invalid format for edit specification";
private static readonly Regex
regex1 = new Regex(#"(?<word>[^,]+),(?<edit>(?:\d+)(?:-(?:\d+))?:(?:[^;]+);?)+", RegexOptions.Compiled),
regex2 = new Regex(#"(?<start>\d+)(?:-(?<end>\d+))?:(?<furigana>[^;]+);?", RegexOptions.Compiled);
static void Main(string[] args)
{
string myString = "子で子にならぬ時鳥,0:こ;2:こ;7-8:ほととぎす";
string result = EditString(myString);
}
private static string EditString(string myString)
{
Match editsMatch = regex1.Match(myString);
if (!editsMatch.Success)
{
throw new ArgumentException(_kinvalidFormatException);
}
int ichCur = 0;
string input = editsMatch.Groups["word"].Value;
StringBuilder text = new StringBuilder();
foreach (Capture capture in editsMatch.Groups["edit"].Captures)
{
Match oneEditMatch = regex2.Match(capture.Value);
if (!oneEditMatch.Success)
{
throw new ArgumentException(_kinvalidFormatException);
}
int start, end;
if (!int.TryParse(oneEditMatch.Groups["start"].Value, out start))
{
throw new ArgumentException(_kinvalidFormatException);
}
Group endGroup = oneEditMatch.Groups["end"];
if (endGroup.Success)
{
if (!int.TryParse(endGroup.Value, out end))
{
throw new ArgumentException(_kinvalidFormatException);
}
}
else
{
end = start;
}
text.Append(input.Substring(ichCur, start - ichCur));
if (text.Length > 0)
{
text.Append(' ');
}
ichCur = end + 1;
text.Append(input.Substring(start, ichCur - start));
text.Append(string.Format("[{0}]", oneEditMatch.Groups["furigana"]));
}
if (ichCur < input.Length)
{
text.Append(input.Substring(ichCur));
}
return text.ToString();
}
}
Notes:
This implementation assumes that the edit specifications will be listed in order and won't overlap. It makes no attempt to validate that part of the input; depending on where you are getting your input from you may want to add that. If it's valid for the specifications to be listed out of order, you can also extend the above to first store the edits in a list and sort the list by the start index before actually editing the string. (In similar fashion to the way the other proposed answer works; though, why they are using a dictionary instead of a simple list to store the individual edits, I have no idea…that seems arbitrarily complicated to me.)
I included basic input validation, throwing exceptions where failures occur in the pattern matching. A more user-friendly implementation would add more specific information to each exception, describing what part of the input actually was invalid.
The Regex class actually has a Replace() method, which allows for complete customization. The above could have been implemented that way, using Replace() and a MatchEvaluator to provide the replacement text, instead of just appending text to a StringBuilder. Which way to do it is mostly a matter of preference, though the MatchEvaluator might be preferred if you have a need for more flexible implementation options (i.e. if the exact format of the result can vary).
If you do choose to use the other proposed answer, I strongly recommend you use StringBuilder instead of simply concatenating onto the results variable. For short strings it won't matter much, but you should get into the habit of always using StringBuilder when you have a loop that is incrementally adding onto a string value, because for long string the performance implications of using concatenation can be very negative.
This should do it (and even handle ranged indices), based on the formatting of the input string you have-
using System;
using System.Collections.Generic;
public class stringParser
{
private struct IndexElements
{
public int start;
public int end;
public string value;
}
public static void Main()
{
//input string
string myString = "子で子にならぬ時鳥,0:こ;2:こ;7-8:ほととぎす";
int wordIndexSplit = myString.IndexOf(',');
string word = myString.Substring(0,wordIndexSplit);
string indices = myString.Substring(wordIndexSplit + 1);
string[] eachIndex = indices.Split(';');
Dictionary<int,IndexElements> index = new Dictionary<int,IndexElements>();
string[] elements;
IndexElements e;
int dash;
int n = 0;
int last = -1;
string results = "";
foreach (string s in eachIndex)
{
e = new IndexElements();
elements = s.Split(':');
if (elements[0].Contains("-"))
{
dash = elements[0].IndexOf('-');
e.start = int.Parse(elements[0].Substring(0,dash));
e.end = int.Parse(elements[0].Substring(dash + 1));
}
else
{
e.start = int.Parse(elements[0]);
e.end = e.start;
}
e.value = elements[1];
index.Add(n,e);
n++;
}
//this is the part that takes the "setup" from the parts above and forms the result string
//loop through each of the "indices" parsed above
for (int i = 0; i < index.Count; i++)
{
//if this is the first iteration through the loop, and the first "index" does not start
//at position 0, add the beginning characters before its start
if (last == -1 && index[i].start > 0)
{
results += word.Substring(0,index[i].start);
}
//if this is not the first iteration through the loop, and the previous iteration did
//not stop at the position directly before the start of the current iteration, add
//the intermediary chracters
else if (last != -1 && last + 1 != index[i].start)
{
results += word.Substring(last + 1,index[i].start - (last + 1));
}
//add the space before the "index" match, the actual match, and then the formatted "index"
results += " " + word.Substring(index[i].start,(index[i].end - index[i].start) + 1)
+ "[" + index[i].value + "]";
//remember the position of the ending for the next iteration
last = index[i].end;
}
//if the last "index" did not stop at the end of the input string, add the remaining characters
if (index[index.Keys.Count - 1].end + 1 < word.Length)
{
results += word.Substring(index[index.Keys.Count-1].end + 1);
}
//trimming spaces that may be left behind
results = results.Trim();
Console.WriteLine("INPUT - " + myString);
Console.WriteLine("OUTPUT - " + results);
Console.Read();
}
}
input - 子で子にならぬ時鳥,0:こ;2:こ;7-8:ほととぎす
output - 子[こ]で 子[こ]にならぬ 時鳥[ほととぎす]
Note that this should also work with characters the English alphabet if you wanted to use English instead-
input - iliketocodeverymuch,2:A;4-6:B;9-12:CDEFG
output - il i[A]k eto[B]co deve[CDEFG]rymuch
I have almost designed a notepad using c#. But only problem I'm facing now is in my statusstrip.
My need- I want to display character count per each line.
When user press enter key it should come to new line and now character count should start from 1.
Technically - Col=1, Ln=1; //(initially)Col=no of character per line Ln=line count
When user press enter key-
Ln=2 and goes on and Col=No of characters we have typed in that specific line
I've tried these lines of code -
private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
int count = Convert.ToInt32(e.KeyChar);
if (Convert.ToInt32(e.KeyChar) != 13)
{
Col = richTextBox1.Text.Length;
toolStripStatusLabel1.Text = "Col:" + Col.ToString() + "," + "Ln:" + Ln;
}
if (Convert.ToInt32(e.KeyChar) == 13)
{
//richTextBox1.Clear();
Ln = Ln + 1;
toolStripStatusLabel1.Text = "Col:" + Col.ToString() + "Ln:" + Ln;
}
}
Supposing you are using Windows Forms, you can use the following solution (but you have to subscribe to the SelectionChanged event instead of the KeyPress event of the rich text box control):
private void richTextBox1_SelectionChanged(object sender, EventArgs e)
{
int currentIndex = richTextBox1.SelectionStart;
// Get the line number of the cursor.
Ln = richTextBox1.GetLineFromCharIndex(currentIndex);
// Get the index of the first char in the specific line.
int firstLineCharIndex = richTextBox1.GetFirstCharIndexFromLine(Ln);
// Get the column number of the cursor.
Col = currentIndex - firstLineCharIndex;
// The found indices are 0 based, so add +1 to get the desired number.
toolStripStatusLabel1.Text = "Col:" + (Col + 1) + " Ln:" + (Ln + 1);
}
I made this small nested for loop, and it shows no error in C# whatsoever,
but when I try to run my small program I get the following error in my TextBox:
System.Windows.Forms.TextBox, Text: System.Windows.Forms.TextBox,
Text: Syst...
Here is my code:
int number = textBox.Text..ToString();
for (int row = 0; row < number; row++)
{
for (int x = number - row; x > 0; x--)
{
textBox2.Text = textBox2.Text + "X";
}
textBox2.Text = textBox2 + Environment.NewLine;
}
My result should be something like this:
XXXX
XXX
XX
X
I can't figure out what may cause this error.
You can't assign a string to a number. You need to convert it:
// int number = textBox.Text..ToString();
int number;
if (!int.TryParse(textBox.Text, out number)
{
// Handle improper input...
}
// Use number now
In addition, when you add the newline, you need to actually append to the Text property, not the TextBox itself:
textBox2.Text = textBox2.Text + Environment.NewLine;
Instead of
textBox2.Text = textBox2 +
use
textBox2.Text = textBox2.Text +
in the last line.
That's it ;-)
textBox2.Text = textBox2 + Environment.NewLine;
Should be
textBox2.Text = textBox2.Text + Environment.NewLine;
System.Windows.Forms.TextBox is just class name
You're missing a .Text in the second to last line. It should be:
textBox2.Text = textBox2.Text + Environment.NewLine;
^^^^^
or just:
textBox2.Text += Environment.NewLine;
int number = textBox.Text..ToString();
Suppose that was a typo? Either way, check if the value is numeric first.
if (int.TryParse(textBox.Text, out number))
{
//run your loop here
}
Also,
textBox2.Text = textBox2 + Environment.NewLine;
should be:
textBox2.Text = textBox2.Text + Environment.NewLine;
You cannot assign string to an int , what you are doing as:
int number = textBox.Text..ToString();
Better option is to use int.TryParse(textBox.Text, out number)
AND
Change
textBox2.Text = textBox2 + Environment.NewLine;
to
textBox2.Text = textBox2.text + Environment.NewLine;
Edit:
Even if you change 2 dots to 1, it will give error for int number = textBox.Text.ToString(); - you can't assign string to int
You have two dots here.
textBox.Text..ToString();
This should throw a compilation error by the way. And you can't assign it to a variable of type integer.
textBox2.Text = textBox2 + Environment.NewLine;
You have to call a method of the textbox here, presumably textBox2.Text.
This might inspire you to think about this problem differently:
// I created a simple textbox class so I could do this in a console app
var textBox = new TextBox();
var textBox2 = new TextBox();
textBox.Text = "4";
var number = Convert.ToInt32(textBox.Text);
var descendingXStrings = Enumerable.Range(1, number)
.Select(n => new string('X', n))
.Reverse();
textBox2.Text = string.Join(Environment.NewLine, descendingXStrings);
Console.WriteLine(textBox2.Text);
CW as this does not answer the question directly.
Try this
int number = int.Parse(textBox1.Text);
for (int row = 0; row < number; row++)
{
for (int x = number - row; x > 0; x--)
{
textBox2.Text = textBox2.Text + "X";
}
textBox2.Text = textBox2.Text + Environment.NewLine;
}
Convert TextBox Value in integer
Change textBox2 to textBox2.Text in second last line
Use textBox as multiline textbox
I want to count the words in richtextbox. First, i input a word in textbox1(for searching), and press "count" button, textbox2 will show a number about how many the same words in the richtextbox. Here are my codes, but it doesn't work, the textbox2 always shows 0.Thank you for your help.
private void button2_Click(object sender, EventArgs e)
{
string a=richTextBox1.Text;
string b=textBox1.Text;
for (int i = 0; i < a.Length; i++)
{
int n=0;
if (a.Equals(b))
{
n++;
}
textBox2.Text = n.ToString();
}
}
You need to compare the individual word to b, not the whole sentence. You can use the following code as a reference:
string[] data = richTextBox1.Text.Split(' ');
for(int i=0;i<data.Length;i++)
{
if(data[i]==textBox1.Text)
n++;
}
Try this one:
string data = richTextBox1.Text;
var target = textBox1.Text;
var count = data.Select((c, i) => data.Substring(i))
.Count(sub => sub.ToUpper()
.StartsWith(target));
textBox2.Text = count;
It's a bit more easier to show word count for richtextbox like this:
Dim wordcount As Integer
Dim a As String() = RichTextBox1.Text.Split(" ")
wordcount = a.Length
You can use 'wordcount' for the word count. For example:
Label1.Text = "Word Count: " & wordcount