I'm trying to count the number of words and characters in a specific text. Now this all works fine but I want to tidy up code so that I don't have to include the the you see under newSummaryMethod() into every button, hence why I have placed it in it's own method. But when I do this, it doesn't count the words and characters. Now I know the reason is that string copyText = ""; in the method, that's because if I don't declare that string variable, then I will get syntax errors in my button that copyText is not declared.
My question is really about how can I get the newSummaryMethod to know that it needs to communication with the copyText in first the vowels button? I have another button where copyText may behave a bit differently so I think I need the button to communicate with the method.
private void newSummaryMethod() {
string copyText = "";
/*Count number of lines in processed text,
extra line is always counted so -1 brings it to correct number*/
int numLines = copyText.Split('\n').Length - 1;
//seperate certain characters in order to find words
char[] seperator = (" " + nl).ToCharArray();
//number of words, characters and include extra line breaks variable
int numberOfWords = copyText.Split(seperator, StringSplitOptions.RemoveEmptyEntries).Length;
int numberOfChar = copyText.Length - numLines;
//Unprocessed Summary
newSummary = nl + "Word Count: " + numberOfWords + nl + "Characters Count: " + numberOfChar;
}
private void btnVowels_Click(object sender, EventArgs e) {
//Strip vowels
string vowels = "AaEeIiOoUu";
string copyText = richTextBox1.Text;
copyText = new string(copyText.Where(c => !vowels.Contains(c)).ToArray());
newSummaryMethod();
//Write into richTextBox2
wholeText = richTextBox1.Text + oldSummary + copyText + newSummary;
Write(Second_File, wholeText);
richTextBox2.Text = wholeText;
}
private void btnAlpha_Click(object sender, EventArgs e) {
//Remove non alpha characters
string nonAlpha = #"[^A-Za-z ]+";
string addSpace = "";
string copyText = richTextBox1.Text;
copyText = Regex.Replace(copyText, nonAlpha, addSpace);
newSummaryMethod();
//Write into richTextBox2
wholeText = richTextBox1.Text + oldSummary + copyText + nl + newSummary;
Write(Second_File, wholeText);
richTextBox2.Text = wholeText;
}
you can pass the data the method needs to it as an argument
private void newSummaryMethod(string copyText) {...}
and then call it like
newSummaryMethod(copyText);
another way is declaring your variable outside the function scope so both functions will have access to it.
string copyText = null; //added
private void newSummaryMethod() {
copyText = ""; //changed
/*Count number of lines in processed text,
extra line is always counted so -1 brings it to correct number*/
int numLines = copyText.Split('\n').Length - 1;
//seperate certain characters in order to find words
char[] seperator = (" " + nl).ToCharArray();
//number of words, characters and include extra line breaks variable
int numberOfWords = copyText.Split(seperator, StringSplitOptions.RemoveEmptyEntries).Length;
int numberOfChar = copyText.Length - numLines;
//Unprocessed Summary
newSummary = nl + "Word Count: " + numberOfWords + nl + "Characters Count: " + numberOfChar;
}
private void btnVowels_Click(object sender, EventArgs e) {
//Strip vowels
string vowels = "AaEeIiOoUu";
copyText = richTextBox1.Text; //changed
copyText = new string(copyText.Where(c => !vowels.Contains(c)).ToArray());
newSummaryMethod();
//Write into richTextBox2
wholeText = richTextBox1.Text + oldSummary + copyText + newSummary;
Write(Second_File, wholeText);
richTextBox2.Text = wholeText;
}
private void btnAlpha_Click(object sender, EventArgs e) {
//Remove non alpha characters
string nonAlpha = #"[^A-Za-z ]+";
string addSpace = "";
copyText = richTextBox1.Text; //changed
copyText = Regex.Replace(copyText, nonAlpha, addSpace);
newSummaryMethod();
//Write into richTextBox2
wholeText = richTextBox1.Text + oldSummary + copyText + nl + newSummary;
Write(Second_File, wholeText);
richTextBox2.Text = wholeText;
}
Related
I am trying to make a hex to string converter and for some reason the spacing between bytes in the conversion is multiplied by 2.
I would like it to spit out a single space between characters,
private void button2_Click(object sender, EventArgs e)
{
try
{
textBox1.Clear();
textBox2.Text = textBox2.Text.Replace(" ", "");
string StrValue = "";
while (textBox2.Text.Length > 0)
{
StrValue += System.Convert.ToChar(System.Convert.ToUInt32(textBox2.Text.Substring(0, 2), 16)).ToString();
textBox2.Text = textBox2.Text.Substring(2, textBox2.Text.Length - 2);
textBox1.Text = textBox1.Text + StrValue + " ";
}
}
catch (Exception ex)
{
MessageBox.Show("Conversion Error Occurred : " + ex.Message, "Conversion Error");
}
}
so "41 41" converted would look like "A A", but this is what happens:
image
Does anybody see what I am doing wrong?
In this line
textBox1.Text = textBox1.Text + StrValue + " ";
you consequently append the result of calculations to your TextBox1.
So, after the first iteration the result is A, you append it and a whitespace to TextBox1.
Then, you take the second 41 and convert it. Now, StrValue is AA and you append it and space to TextBox1, and so on.
You need to move this line out of your while loop:
textBox1.Clear();
textBox2.Text = textBox2.Text.Replace(" ", "");
string StrValue = "";
while (textBox2.Text.Length > 0)
{
StrValue += System.Convert.ToChar(System.Convert.ToUInt32(textBox2.Text.Substring(0, 2), 16)).ToString();
textBox2.Text = textBox2.Text.Substring(2, textBox2.Text.Length - 2);
}
textBox1.Text = StrValue;
As some people mentioned in comments, you need to stop working with TextBoxes this way. It is pretty confusing. You may want to do the following:
private string HexToString(string hex)
{
string result = "";
while (hex.Length > 0)
{
result += Convert.ToChar(Convert.ToUInt32(hex.Substring(0, 2), 16));
hex = hex.Substring(2); // no need to specify the end
}
return result;
}
Then, in your button click event or wherever else:
textBox1.Text = HexToString(textBox2.Text.Replace(" ", ""));
As simple as that. Or you can even move replacing the whitespaces in the method. Now, this code is readable and is logically separated.
The problem seems to be caused by the accumulated value in StrValue. You should define that variable inside your while, and assign it only (don't append a new value).
while (textBox2.Text.Length > 0)
{
string StrValue = System.Convert.ToChar(System.Convert.ToUInt32(textBox2.Text.Substring(0, 2), 16)).ToString();
textBox2.Text = textBox2.Text.Substring(2, textBox2.Text.Length - 2);
textBox1.Text = textBox1.Text + StrValue + " ";
}
I have two buttons that contain their own functionality (which I have not included in the code snippet below as it is not relevant), but they also contain the same block of text (which is shown in the code snippet below). My question as I am a beginner in C#, is there a way where I can just write the code once and use the function shall I call to be placed in the buttons instead?
Code Snippet:
private void btnAlpha_Click(object sender, EventArgs e)
{
//Replace Non Alpha code would go here…
/*Count number of lines in processed text,
extra line is always counted so -1 brings it to correct number*/
int numLines = copyText.Split(“/n”).Length - 1;
//seperate certain characters in order to find words
char[] seperator = (" " + nl).ToCharArray();
//number of words, characters and include extra line breaks variable
int numberOfWords = copyText.Split(seperator, StringSplitOptions.RemoveEmptyEntries).Length;
int numberOfChar = copyText.Length - numLines;
//Unprocessed Summary
newSummary = nl + "Word Count: " + numberOfWords + nl + "Characters Count: " + numberOfChar;
}
private void btnReplace_Click(object sender, EventArgs e)
{
//Replace code would go here…
/*Count number of lines in processed text,
extra line is always counted so -1 brings it to correct number*/
int numLines = copyText.Split(“/n”).Length - 1;
//seperate certain characters in order to find words
char[] seperator = (" " + nl).ToCharArray();
//number of words, characters and include extra line breaks variable
int numberOfWords = copyText.Split(seperator, StringSplitOptions.RemoveEmptyEntries).Length;
int numberOfChar = copyText.Length - numLines;
//Unprocessed Summary
newSummary = nl + "Word Count: " + numberOfWords + nl + "Characters Count: " + numberOfChar;
}
In C# you can enclose reusable code in methods (as suggested in comments). If there are parts of the code that behave differently then again you can encapsulate them into a separate methods. Below the code that's repeated in each handler is in MyMethod. btnReplace specific code is in MyReplace and btnAlpha specific code is in MyAlpha:
private void btnReplace_Click(object sender, EventArgs e)
{
MyReplace();
MyMethod();
}
private void btnAlpha_Click(object sender, EventArgs e)
{
MyAlpha();
MyMethod();
}
private void MyReplace()
{
// Replace code
}
private void MyAlpha()
{
// Alfa code
}
private void MyMethod()
{
//Replace code would go here…
/*Count number of lines in processed text,
extra line is always counted so -1 brings it to correct number*/
int numLines = copyText.Split(“/n”).Length - 1;
//seperate certain characters in order to find words
char[] seperator = (" " + nl).ToCharArray();
//number of words, characters and include extra line breaks variable
int numberOfWords = copyText.Split(seperator, StringSplitOptions.RemoveEmptyEntries).Length;
int numberOfChar = copyText.Length - numLines;
//Unprocessed Summary
newSummary = nl + "Word Count: " + numberOfWords + nl + "Characters Count: " + numberOfChar;
}
If you need some sort of communication between the methods then one option would be to return a value from the first method and pass it into the second one.
Alternatively you can parameterize your main method (if true execute alfa part else execute replace part) and execute it with a parameter saying which part of the code to execute. But if there are many possible alternatives than probably producing separate method for each alternative makes more sense.
I am almost finished with the program, but my output is wrong, and after 5 hours, I am still unable to figure out what I did wrong, and thought it may be helpful to seek a fresh set of eyes. I have a Demo program given by my instructor, so I took a screen shot to show clearly what it should look like.
My code for that chunk is this:
//array add student data to the array
if (currentStudentArrayIndex >= constArrayMaxSize)
{
MessageBox.Show("Array is full, cannot add any more to the array");
}
else
{
arrayNames [currentStudentArrayIndex] = studentName;
arrayGrades [currentStudentArrayIndex] = studentGrade;
MessageBox.Show("Student data has been entered into array index " + currentStudentArrayIndex);
textBoxName.Text = "";
textBoxGrade.Text = "";
}
//array output
currentStudentArrayIndex = currentStudentArrayIndex + 1;
}
//array display
private void buttonDisp_Click(object sender, EventArgs e)
{
string myString = "";
string studentName = "";
int studentGrade = 0;
myString = "Student Data Entered So Far:\n";
//loop through array
for(int i = 0; i < arrayNames.Length; i++)
{
myString = myString +
"Array[" + i + "] ==> " +
"Student #" + (i + 1);
if (arrayGrades[i] == 0)
{
myString = myString + " (NOT ENTERED)";
}
else
{
myString = myString +
" Name:" +arrayNames[i] +
" Grade:" + arrayGrades[i].ToString("c");
studentName = studentName + arrayNames[i];
studentGrade = studentGrade + arrayGrades[i];
}
//output
labelDisplay.Text = myString;
}
Obviously myString isn't working, but I'm unsure why, what did I do to it? Any suggestions, useful links, or guidance is much appreciated!
Button buttonDisp was incorrect. Using the correct button name corrected the problem, allowing the information to display properly.
I am new to programming and having problems making a simple code for character counter for a button. I've somehow managed to code a line together that actually counts words. here it is:
private void button_add_Click(object sender, EventArgs e)
{
string count = richTextBox.Text;
label_info.Text = "Word count is " + (count.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries).Length).ToString();
//Trying to add a new character count down here
// label_info.Text = "Character count is " + ....code ...;
}
Any advice would be appreciated.
EDIT: Thanks to you all i got my answer here:
private void button_add_Click(object sender, EventArgs e)
{
string count = richTextBox.Text;
label_info.Text = "Word count is " + (count.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries).Length).ToString();
label_info.Text = "\nCharacter count is " + richTextBox.Text.Lenth;
}
Try using string's Length property.
label_info.Text = label_info.Text + "\nCharacter count is " + richTextBox.Text.Lenth;
You are splitting the string on each space and counting the length of the resulting array. If you want the length of the string (with whitespace etc.) you can do this:
label_info.Text = "Character count is " + count.length;
If you don't want the whitespace you can do this:
label_info.Text = "Character count is " + count.Replace(" ", "").length;
You don't have to write a complex code. You can count characters using length property. See below sample codes. In it we use a Textbox and a Label, Label shows the count of characters entered in the textbox.
void textBox1_TextChanged(object sender, EventArgs e)
{
lablename.Text = textboxname.Text.length.Tostring();
}
I have also created its video tutorial. Watch it on YouTube
string a = richTextBox1.Text;
label2.Text = a.Length.ToString();
I have a DataGridView with four Columns and need to crate a multiline string from its content, separated by comma.
This code works, but probably - there is a more elegant way:
string multiLine = "";
string singleLine;
foreach (DataGridViewRow r in dgvSm.Rows)
{
if (!r.IsNewRow)
{
singleLine = r.Cells[0].Value.ToString() + ","
+ r.Cells[1].Value.ToString() + ","
+ r.Cells[2].Value.ToString() + ","
+ r.Cells[3].Value.ToString() + Environment.NewLine;
multiLine = multiLine + singleLine;
}
}
I don't know about elegant, but:
use StringBuilder for string manipulation, type string is immutable!
if you need to do something in between, separate first or last cycle running (e.g. comma separation)
So, basically something like this:
StringBuilder multiLine = new StringBuilder();
foreach (DataGridViewRow r in dgvSm.Rows)
{
if (!r.IsNewRow)
{
if (r.Cells.Count > 0)
{
multiLine.Append(r.Cells[0].Value.ToString()); //first separated
for (int i = 1; i < r.Cells.Count; ++i)
{
singleLine.Append(','); //between values
singleLine.Append(r.Cells[i].Value.ToString());
}
multiLine.AppendLine();
}
}
}
To illustrate speed difference between StringBuilder concatenation (just dynamic array of characters) and string (new object and copy everything each time you use operator + concatenation), have a look at mini-program:
public static void Main()
{
var sw = new Stopwatch();
sw.Start();
StringBuilder s = new StringBuilder();
//string s = "";
int i;
for (i = 0; sw.ElapsedMilliseconds < 1000; ++i)
//s += i.ToString();
s.Append(i.ToString());
sw.Stop();
Console.WriteLine("using version with type " + s.GetType().Name + " I did " +
i + " times of string concatenation.");
}
For my computer it is:
using version with type String I did 17682 times of string concatenation.
using version with type StringBuilder I did 366367 times of string concatenation.
Try this :
string multiLine = "";
string singleLine;
foreach (DataGridViewRow r in dgvSm.Rows)
{
if (!r.IsNewRow)
{
singleLine = r.Cells[0].Value.ToString() + ","
+ r.Cells[1].Value.ToString() + ","
+ r.Cells[2].Value.ToString() + ","
+ r.Cells[3].Value.ToString() + "\r\n";
multiLine = multiLine + singleLine;
}
}