I have the following text in my RIchTextBox:
foo:baa#done baa
a:b#pending ee
and I want highlight all after # and before " "(espace)
How I do this? I tried make the end as IndexOf of \t or " " but it returns -1.
My code(not working as expected):
string[] lines = list.Lines;
string line;
for (int i = 0, max = lines.Length; i < max; i++)
{
line = lines[i];
int start = list.Find("#");
int end = ??? // I tried list.Find("\t") and list.Find(" ")
if (-1 != start || -1 != end)
{
list.Select(start, end);
list.SelectionColor = color;
}
}
list is an RichTextBox
Use GetLineFromCharIndex() to get the line number of the Find() method return value. Then GetFirstCharIndexFromLine(line + 1) to know where the next line starts. That gives you the SelectionStart and SelectionLength values you need to highlight the text.
try this:
string[] lines = list.Lines;
string line;
int len = 0;
for (int i = 0, max = lines.Length; i < max; i++)
{
line = lines[i];
int j = i == 0 ? 0 : len;
string str = Regex.Match(line, #"#.*$").Value;
if (!string.IsNullOrEmpty(str))
{
int start = list.Find(str, j, RichTextBoxFinds.None);
if (start != -1)
{
list.Select(start, str.Length);
list.SelectionColor = Color.Red;
}
len += line.Length;
}
}
Maybe you should use line.IndexOf instead of list.Find?
In short, you seem to be searching for characters in your List control, not in the string line.
Related
I created following to count number of words. Now I need to remove all spaces using IndexOf. I'm stuck. Can someone help? It has to be something simple, but I cant figure it out.
string text = "Hello. What time is it?";
int position = 0;
int noSpaces = 0;
for (int i = 0; i < text.Length; i++)
{
position = text.IndexOf(' ', position + 1);
if (position != -1)
{ noSpaces++; }
if (position == -1) break;
}
Console.WriteLine(noSpaces + 1);
If you are looking to just remove the spaces in your text so it would look like: Hello.Whattimeisit? then all you need to do is use String.Replace:
string text = "Hello. What time is it?";
string textWithNoSpaces = text.Replace(" ", "");
Console.WriteLine(textWithNoSpaces); // will print "Hello.Whattimeisit?"
If you are looking to split the text into separate words then you would want to use String.Split:
string text = "Hello. What time is it?";
string[] words = text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // "RemoveEmptyEntries" will remove any entries which are empty: ""
// words[0] > Hello.
// words[1] > What
// etc.
You then can get a count of how many words are in the text and then combine them, using String.Concat, if you need text in the form of Hello.Whattimeisit?:
int numberOfWords = words.Length;
string textWithNoSpaces = string.Concat(words);
Update: This is how you would count the number of words and remove spaces using String.IndexOf & String.Substring:
This is a really sloppy example, but it gets the job done
string text = "Hello. What time is it?";
string newText = string.Empty;
int prevIndex = 0;
int index1 = 0;
int index2 = 0;
int numberOfWords = 0;
while (true)
{
index1 = text.IndexOf(' ', prevIndex);
if (index1 == -1)
{
if (prevIndex < text.Length)
{
newText += text.Substring(prevIndex, (text.Length - prevIndex));
numberOfWords += 1;
}
break;
}
index2 = text.IndexOf(' ', (index1 + 1));
if ((index2 == -1) || (index2 > (index1 + 1)))
{
newText += text.Substring(prevIndex, (index1 - prevIndex));
numberOfWords += 1;
}
prevIndex = (index1 + 1);
}
Console.WriteLine(numberOfWords); // will print 5
Console.WriteLine(newText); // will print "Hello.Whattimeisit?"
Console.ReadLine();
If your requirement is to count the number of words, can't you try this?
string text = "Hello. What time is it?";
var arr = text.Split(' ');
var count = arr.Length;
.Net Fiddle
Strings are immutable so you cant achieve it with only IndexOf that will require multiple changes. if you need to achieve it with that particular method I think that StringBuilder is the only way. However if this is not some assignment and you plan to use it in real application I strongly dissuade because it is really process heavy.
Can anyone help me to find most efficient way to print character occurrence along with that character in a given string in alphabetical order?
I am able to count occurrence of character in string but I am not able to sort it in alphabetical order.
string OutputString = string.Empty;
int count = 1;
char[] charArr = inputString.ToCharArray();
for (int i = 0; i < charArr.Length; i++) {
for (int j = i + 1; j < charArr.Length; j++) {
if (charArr[i] == charArr[j])
count++;
}
if (!OutputString.Contains(charArr[i]))
OutputString += charArr[i].ToString() + count.ToString();
count = 1;
}
OutputString = string.Concat(OutputString.OrderBy(c => c));
let's say input string in xgdgyd
output should be:
d2g2x1y1.
You can use Linq to simplify this:
string s = "xgdgyd";
var result = s
.GroupBy(c => c)
.Select(g => g.Key.ToString() + g.Count())
.OrderBy(x => x);
Console.WriteLine(string.Concat(result)); // Outputs "d2g2x1y1"
The most useful thing here is GroupBy(), which will group all identical items together. That allows us to use g.Count() to count the number of items in each group.
Then we just concatenate each group key (a char) with its count into a single string.
Example on .Net Fiddle.
(I've simplified the code to use string.Concat() rather than string.Join() here.)
Solution given by #Matthew with LINQ is perfect, but if you want a solution with for loops as you posted in question then do this.
sort inputString first, and remove the line of code that sorts OutputString at the end, like this::
string inputString = "xgdgyd";
inputString = string.Concat(inputString.OrderBy(c => c));
string OutputString = string.Empty;
int count = 1;
char[] charArr = inputString.ToCharArray();
for (int i = 0; i < charArr.Length; i++)
{
for (int j = i + 1; j < charArr.Length; j++)
{
if (charArr[i] == charArr[j])
count++;
}
if (!OutputString.Contains(charArr[i]))
OutputString += charArr[i].ToString() + count.ToString();
count = 1;
}
Since you might not yet know LINQ, here is a solution using "classic" techniques:
string input = "xgdgyd";
char[] charArr = input.ToCharArray();
Array.Sort(charArr); // Sort before counting as Gian Paolo suggests!
// ==> "ddggxy"
int count;
string output = "";
for (int i = 0; i < charArr.Length; i += count) { // Increment by count to get
// the next different char!
count = 1;
// Note that we can combine the conditions within the for-statement
for (int j = i + 1; j < charArr.Length && charArr[j] == charArr[i]; j++) {
count++;
}
output += charArr[i] + count.ToString();
}
Console.WriteLine(output); // ==> d2g2x1y1
Note that the increment i += count, which is equivalent to i = i + count is performed at the end of the for-loop. Therefore count will be initialized at this point.
Another variant that uses only one loop instead of two nested loops appends the previous character to the output and resets the counter as soon as a different character is found.
string input = "xgdgyd";
char[] charArr = input.ToCharArray();
Array.Sort(charArr); // Sort before counting as Gian Paolo suggests!
int count = 1;
string output = "";
for (int i = 1; i < charArr.Length; i++) {
if (charArr[i] == charArr[i - 1]) {
count++;
} else {
output += charArr[i - 1] + count.ToString();
count = 1;
}
}
// Output last char
output += charArr[charArr.Length - 1] + count.ToString();
Console.WriteLine(output);
A more advanced technique would be to use a StringBuilder. See Concatenating Strings Efficiently by Jon Skeet.
I have text file so it looks like this.
Some old wounds never truly heal, and bleed again at the slightest word.
Fear cuts deeper than swords.
Winter is coming.
If I look back I am lost.
Nothing burns like the cold.
and I need to make that lines to be same length as longest one adding spaces
static void Reading(string fd, out int nr)
{
string[] lines = File.ReadAllLines(fd, Encoding.GetEncoding(1257));
int length = 0;
nr = 0;
int nreil = 0;
foreach (string line in lines)
{
if (line.Length > length)
{
length = line.Length;
nr = nreil;
}
nreil++;
}
}
edit: simply padding the sentences with whitespaces between words
EDIT: Since OP specified they wanted spacing between words, I have removed my end of line padding example, leaving only the justify code.
string[] lines = File.ReadAllLines(fd, Encoding.GetEncoding(1257));
int maxLength = lines.Max(l => l.Length);
lines = lines.Select(l => l.Justify(maxLength)).ToArray();
public static string Justify(this string input, int length)
{
string[] words = input.Split(' ');
if (words.Length == 1)
{
return input.PadRight(length);
}
string output = string.Join(" ", words);
while (output.Length < length)
{
for (int w = 0; w < words.Length - 1; w++)
{
words[w] += " ";
output = string.Join(" ", words);
if (output.Length == length)
{
break;
}
}
}
return output;
}
How can I add additional 30 character from the char that matches where in my code below.
private void CheckGarbageCharacters(string input)
{
var contentList = File.ReadAllLines(input).ToList();
int[] lineno = { 0 };
foreach (var line in contentList)
{
lineno[0]++;
foreach (var errorModel in from c in line
where c > '\u007F'
select new ErrorModel
{
Filename = Path.GetFileName(input),
LineNumber = lineno[0],
ErrorMessage = "Garbage character found.",
Text = c.ToString()
})
{
_errorList.Add(errorModel);
}
}
}
I'm not sure I fully understand your question but based on the code you have provided it seems like you are trying to do something like this...
~ Pseudo Code ~ This has not been tested ~
private void CheckGarbageCharacters(string filename)
{
var lines = File.ReadAllLines(filename).ToList();
for (int i = 0; i < lines.Count; i++)
{
var line = lines[i];
for (int j = 0; j < line.Length; j++)
{
var c = line[j];
if (c > '\u007F')
{
// Grab the next 30 characters after 'c'
var text = c.ToString();
for (int k = 0; k < 30; k++)
{
if ((j + k) > (line.Length - 1))
{
break;
}
text += line[j + k].ToString();
}
// Create the error message
var error = new ErrorModel()
{
Filename = Path.GetFileName(filename),
LineNumber = i,
ErrorMessage = "Garbage character found.",
Text = text
};
// Add the error to the list
_errorList.Add(error);
}
}
}
}
I'm not sure what you mean by "add additional 30 characters from the char that matches where in my code" though.
EDIT
I've updated my answer according to the information you've provided in the comments. I believe this is what you are trying to do here.
Something that looks like this:
Is there a line-like property where I could do?:
foreach line ...
line.BackColor = Colors.Gray;
Lines[i] property returns just a string.
A not so great solution would be to append extra text onto each line and then highlight the full text. So something like this:
// Update lines to have extra length past length of window
string[] linez = new string[richTextBox1.Lines.Length];
for (int i = 0; i < richTextBox1.Lines.Length; i++)
{
linez[i] = richTextBox1.Lines[i] + new string(' ', 1000);
}
richTextBox1.Clear();
richTextBox1.Lines = linez;
for(int i = 0; i < richTextBox1.Lines.Length; i++)
{
int first = richTextBox1.GetFirstCharIndexFromLine(i);
richTextBox1.Select(first, richTextBox1.Lines[i].Length);
richTextBox1.SelectionBackColor = (i % 2 == 0) ? Color.Red : Color.White;
richTextBox1.SelectionColor = (i % 2 == 0) ? Color.Black : Color.Green;
}
richTextBox1.Select(0,0);
It would look like this: