Select text from line A to line B in richtextbox - c#

i'm looking for a way to select text between two lines (A and B) in a richtextbox.
I tried something like this:
richTextBox1.Select
(
richTextBox1.GetFirstCharIndexFromLine(parentesi_inizio[current_idx]),
(
richTextBox1.GetFirstCharIndexFromLine(parentesi_fine[current_idx]) -
richTextBox1.GetFirstCharIndexFromLine(parentesi_inizio[current_idx]) + 1
)
);
Inside parentesi_inizio and parentesi_fine i have the line number, i should select from line A (parentesi_inizio) to B (parentesi_fine).
After some tests i think the problem is this:
richTextBox1.GetFirstCharIndexFromLine(parentesi_fine[current_idx]) -
richTextBox1.GetFirstCharIndexFromLine(parentesi_inizio[current_idx]) + 1
This code works fine at first, but I noticed that after a while 'begins to show results stoner.
I did further testing and the lines are correct (ie, refer to the right spot) whereas "Select" does not select the entire portion or does it incorrectly (selecting parts that do not have to)
( I used google translate for the last part )
EDIT:
Imagine this text:
Hello
World || A points here (Line 1)
Guys!
This
is
a || B points here (Line 5)
line
I need to Select (not get text) this text:
World
Guys!
This
is
a
in the richtextbox.
Example images:
Case 1:
Case 2:
Thats is what i want and what the code i posted do, but after a while the code starts to bug as i said above (at the start).
EDIT 2:
I changed my code to this after varocarbas reply
richTextBox1.Select (
richTextBox1.GetFirstCharIndexFromLine(parentesi_inizio[current_idx]),
richTextBox1.GetFirstCharIndexFromLine(parentesi_inizio[current_idx])
+ count_length(parentesi_inizio[current_idx], parentesi_fine[current_idx]) );
where count_length is
private int count_length(int A, int B)
{
// A => first line
// B => last line
int tot = 0;
for (int i = A; i <= B; ++i)
{
// read the length of every line between A and B
tot += richTextBox1.Lines[i].Length - 1;
}
// return it
return tot;
}
but now the code not work in every case.. anyway here is a screen of a bugged case using the old code (the code posted at the start of the question)
(source: site11.com)
it select right from the first { but not reach the last } (i do some checks here and the problem is the subtraction not the lines num.)
EDIT 3:
I'm ready sorry varocarbas, i think i just wasted your time.. after see my screen i noticed the problem might be the word wrap i tried to disable it and seems now works ok.. sorry for your time.

Why not relying on the lines[] array directly?
string line2 = richTextBox1.lines[1];
Bear in mind that it has its own indexing, that is, to get the first character in the third line you can do:
int firstChar3 = richTextBox1.lines[2].Substring(0, 1);
To refer to the whole richTextBox indexing system, you can rely also on GetFirstCharIndexFromLine. That is:
int startIndexLine2 = richTextBox1.GetFirstCharIndexFromLine(1); //Start index line2
int endIndexLine2 = startIndexLine2 + richTextBox1.lines[1].length - 1; //End index line2
-------- AFTER UPDATED QUESTION
Sorry about that, but I cannot see the code in the links you provided. But the code below should deliver the outputs you want:
int curStart = richTextBox1.GetFirstCharIndexFromLine(2);
richTextBox1.Select(curStart, richTextBox1.Lines[2].Length);
string curText = richTextBox1.SelectedText; -> "Guys!"
curStart = richTextBox1.GetFirstCharIndexFromLine(3);
richTextBox1.Select(curStart, richTextBox1.Lines[3].Length);
curText = richTextBox1.SelectedText; -> "This"
curStart = richTextBox1.GetFirstCharIndexFromLine(4);
richTextBox1.Select(curStart, richTextBox1.Lines[4].Length);
curText = richTextBox1.SelectedText; -> "is"

Related

Is there a way to prevent index out of bounds error here?

I am new here. I'm trying a C# problem on Leetcode about Longest Common Prefix. I know this problem has been solved MANY times. I'm just having a hard time understanding why my code doesn't work under certain conditions. When the input ["flower","flow","flight"] is put in, it works just fine and get the output "fl". However, when I get to the input ["ab", "a"], I suddenly get an IndexOutOfRangeException. Anyone know why? Here's my code:
public class Solution {
public string LongestCommonPrefix(string[] strs) {
StringBuilder sb = new StringBuilder();
int h = 1;
int count = 0;
if (strs.Length == 1){
return strs[0];
}
for (int i = 0; i<strs[0].Length; i++)
{
if ((strs[0])[i].Equals((strs[h])[i])){
count++;
if (h<strs.Length-1){
h++;
}
}
}
for (int j = 0; j < count; j++)
{
sb.Append((strs[0])[j]);
}
return sb.ToString();
}
}
You can debug by making a simple console app in Visual Studio. I added a Console.Writeline(strs[0] + strs[h]) to your code to demonstrate the logic as is. Running your code in debug, you can step through and see where the exception gets thrown:
Notice that the console prints the same thing each time, and that the strs[h] is only one character long. When you increment the i to 1, you're trying to access the second element of a one element array.
When the input ["flower","flow","flight"] is put in, it works just fine and get the output "fl". However, when I get to the input ["ab", "a"], I suddenly get an IndexOutOfRangeException. Anyone know why?
Because the algorithm as written loops until i has reached the length of the first string, not the shortest string. This is fine for flower/flow/flight because all these strings will find the common prefix "fl" before i comes close to running off the end of the shortest string; i is 2 by the time the algorithm determines that the o in flower is different to the i in flight and hence the code doesn't go out of bounds.
In the ab/a case, i is 1 and the algorithm hasn't yet determined the prefixes have diverged, you attempt to access the nonexistent index 1 on string "a" and get a crash
As comments have pointed out you also have a problem on your h logic; h should be cycled starting from 1 in a loop of its own inside the i loop. As it is now h just increments up to the number of strings-1 and stays there so in essence you end up only looking for prefixes in the first and last strings. If your strings were flower/flight/float/flowing/flowers you'd declare a prefix of "flower" because flight/float/flowing would only be considered when i was 0, 1 and 2 respectively
I suggest you write out the algorithm in comments, in the language you think in then have a go at turning it into c#

Search and Replace inside a List with c#

I am a newbie for programming, at this stage I am using an automation software, it supports c# and js.
Is it possible to search each line and replace a word?
Example data
List name: A
Sample data a
Sample data b
Sample data c
To create a c# code so that when there is "a", it changes to x1
This one below is the most close, but it will remove that whole line and replace it with x1. My goal is only to replace a particular word.
If there can be an option to define multiple matches, that would be great.
a > x1
b > x2
c > x3
The code I found that does search and replace, however it remove the whole line that contains this particular match:
The code below will remove whole line that contains a number, and replace it with 1
I found the code in this forum.
var sourceList = project.Lists["A"]; // define list name.
var parserRegex = new Regex("\\d{1,2}"); // it will match all numbers
lock(SyncObjects.ListSyncer)
{
for(int i=0; i < sourceList.Count; i++) // loop through each line.
{
if (parserRegex.IsMatch(sourceList[i])) // to check if there is a match
{
sourceList[i]="1"; // This code do the replacing job, but it replace the whole line, not the string.
}
}
}
With your guys' help, I think I have got what I wanted:
Here is my final code that is working for now. It is not perfect but works for my purpose.
My question still remains is that for replacing command, how to define replacing "a" means only to replace like
Turn "Sample data a" into "sample data x1"
But not to do like "Sx1mple dx1tx1 x1".
Code:
var sourceList = project.Lists["A-Source"]; // define list name.
var parserRegex = new Regex("data"); // it will match all numbers
lock(SyncObjects.ListSyncer)
{
for(int i=0; i < sourceList.Count; i++) // loop through each line.
{
// if (parserRegex.IsMatch(sourceList[i])) // to check if there is a match. This line is commented out and it still works.
{
sourceList[i]= sourceList[i].Replace("a", "x1")
.Replace("b","x2")
.Replace("c","x3")
.Replace("<p>","")
.Replace("<strong>",""); // I added two other lines, to remove like p and strong tags, it works!
}
}
}
The replace pair's left part is the target, and the right part is the final replacing text.
In real examples, it can't just be "a", "b" or "c" because a is not only going to replace a, but also the "a" symbol in word like "data".
C# is powerful, thanks for the generous input!
Like Johannes mentioned in comments, in C# you can use String.Replace()
sourceList[i]= sourceList[i].Replace("a", "x1")
This should work:
var sourceList = project.Lists["A"]; // define list name.
string pattern = #"(?'matched'\d*)";
for (int i = 0; i < sourceList.Count; i++) // loop through each line.
{
foreach (Match m in Regex.Matches(sourceList[i], pattern))
{
Group g = m.Groups["matched"];
if (!string.IsNullOrEmpty(g.Value))
{
sourceList[i] = sourceList[i].Replace(g.Value, "newvalue");
}
}
}

C# need help making sure multiple occurrences of the same letter are noted as a number

I'm programming a periodic table for my school project in C#.
I want to make it so that if I press (for example) the H button 3 times it gets shown as H3. It now only works up to H2 and I have no idea why? Any help is welcome thanks in advance.
private void btn_H_Click(object sender, EventArgs e)
{
txt_Chemical.Text = txt_Chemical.Text + "H";
txt_Mass.Text = txt_Mass.Text + 1.006;
int count = txt_Chemical.Text.TakeWhile(c => c == 'H').Count();
if(count > 1)
{
txt_Chemical.Text = "H" + count;
txt_Mass.Text = txt_Mass.Text + 1.006 * count;
}
}
I have no means now to verify if it is true now, but try:
I think it (working up to two H presses) might be due to this line in your code:
int count = txt_Chemical.Text.TakeWhile(c => c == 'H').Count();
Here is how TakeWhile works - it traverses the list from the beginning and stops at first occurrence that does not satisfy predicate. .
So when you do:
txt_Chemical.Text = "H" + count;
Your third letter becomes the value that count holds. So next time TakeWhile breaks on second element as "HH2".TakeWhile(c => c == 'H') yields two element collection.
Try using separate variable to hold the state (number of times that H has been clicked).
Additionally:
use var instead of int before count - in case you change type later it will help
if you care about precision - and for chemicals I assume you do, do not use double (1.006). Use decimals that guarantee precision (1.006m).

Display every single combination of lower case letters

I am trying to figure out how to print every single combination of lower case letters starting at A, B, C , .. , Z AA, AB , .., ZZ ... AAA, AAB, AAC ... HWESA, HWESB, HWESC ... etc and I want the program to keep printing these endlessly, growing in length by 1 each time Z is found as the last letter.
Code that is have seen online is like this
for(int a = 0; a < alphabet.length; a++)
{
Console.WriteLine(alphabet[a]);
for(int b = 0; b < alphabet.length; b++)
{
Console.WriteLine(alphabet[a]+alphabet[b]);
//With however many for loops you want which correspond to string length
}
}
However, this doesn't work for me because I want the length to go till infinite (or in my program to stop when it matches a hard-coded string).
I have tried the same in java with recursive method , hope you understand the logic and write down in C#.You can check the whole program in the below shared link.
size - if 1 means a,b,c...z
if 2 means aa,ab...zz
public static void recursion(long size,String prefix)//Recursive method
{
// Base case: size is 0, print prefix
if(size==0)
{ System.out.println(prefix);
return;
}
// One by one add all characters from set and recursively
// call for size equals to size-1
for(int i=0;i<26;i++)
{
// Next character of input added
String newPrefix = prefix + s[i];
// Size is decreased, because we have added a new character
recursion(size-1,newPrefix);
}
}
Click Here to View Full Code

problem with binarysearch algorithm

the code below belongs to binary search algorithm,user enter numbers in textbox1 and enter the number that he want to fing with binarysearch in textbox2.i have a problem with it,that is when i enter for example 15,21 in textbox1 and enter 15 in textbox2 and put brakpoint on the line i commented below,and i understood that it doesnt put the number in textbox2 in searchnums(commented),for more explanation i comment in code.thanks in advance
public void button1_Click(object sender, EventArgs e)
{
int searchnums = Convert.ToInt32(textBox2.Text);//the problem is here,the value in textbox2 doesnt exist in searchnums and it has value 0.
int result = binarysearch(searchnums);
MessageBox.Show(result.ToString());
}
public int binarysearch(int searchnum)
{
string[] source = textBox1.Text.Split(',');
int[] nums = new int[source.Length];
for (int i = 0; i < source.Length; i++)
{
nums[i] = Convert.ToInt32(source[i]);
}
int first =0;
int last = nums.Length-1;
while (1<= nums.Length)
{
int mid = (int)Math.Floor(first+last / 2.0);
if (first > last)
{
break;
}
if (searchnum < nums[mid])
{
last = mid - 1;
}
if (searchnum > nums[mid])
{
first = mid + 1;
}
else
{
return nums[mid];
}
}
return -1;
}
First, when you know you can place a breakpoint on a line, you sure know you can step through the whole program and see what values are in each variable or property. So, go ahead, and debug. Among other things you are probably missing data input validation in your program.
Second, your binary search implementation is missing mid recalculation after first or last is updated and a stop condition in case the number being looked for is not found in the array. You have to break the loop in case first == last, regardless if nums[mid] matches or not — nobody said the number from textbox2 must be in the array.
What does it have to do with binary search? The problem seems to be that you can't read the number out of a textbox. Are you sure it's the right textbox? What is it's Text? Also, if you put the breakpoint ON the line that assigns the value to searchnums, it will be 0, because it hasn't been assigned yet, put the breakpoint on the line AFTER.
OK, first of all, I hope you know that binary search won't work if nums isn't sorted.
That said, there are a few problems in the algorithm. First of all, you're not changing any of the key elements in the loop. You're only changing first and last in the loop and they aren't even used there, so the loop's state doesn't change.
So i guess you meant to have this line in the beginning of the loop:
mid = (first +last)/2;
Besides that, you need to check for the very likely event that the number doesn't exist. which means adding this in the beginning of the loop to:
if (last < first) break;
Which of course means that the first point of the array block has passed the last point, which means the block size is negative. first == last may be legal when you get to the last cell in the array.
And the last point is to initiate last as size-1:
int last = nums.Length - 1;
We're talking about array indexes after all.

Categories