I know it may not be a best-practice solution for my problem but I'd tried to remove the first and last specific characters of a string.
Here's a string for example: "product"". I'd like to remove only the first and last " characters so the expected result would be: product".
Here's my code that produced some unexpected results and I'd like to understand why it is working like that.
var productName = "\"product\"\""; // "product""
productName.IndexOf('\"', 0) and productName.LastIndexOf('\"', 0) would be both 0 here at this point.
if (productName.IndexOf('\"', 0) == 0) productName = productName.Remove(productName.IndexOf('\"', 0), 1);
In this condition, IndexOf returns 0 as expected so productName's value will be productName"" at this point. Then, I run the following:
if (productName.LastIndexOf('\"', 0) == 0) productName = productName.Remove(productName.LastIndexOf('\"', 0), 1);
In this condition, LastIndexOf returns -1. It acts as if my variable's length remains the same after Remove but its value is shifted to the left by 1 character. Why is that?
Let's take a look at the docs for string.LastIndexOf(char, int):
Reports the zero-based index position of the last occurrence of a specified string within this instance. The search starts at a specified character position and proceeds backward toward the beginning of the string.
...
startIndex
Int32
The search starting position. The search proceeds from startIndex toward the beginning of this instance.
You're calling:
productName.LastIndexOf('\"', 0)
So you're starting at the first character in your string (index 0), and proceeding towards the beginning looking for a " character. But you're already at the beginning! So you're not going to find anything.
Just use the overloads which don't take a startIndex: you don't need it:
string.IndexOf('"')
string.LastIndexOf('"')
Please try this
var productName = "\"product\"\"";
if (productName.IndexOf('\"', 0) == 0)
productName = productName.Remove(productName.IndexOf('\"', 0), 1);
if (productName.LastIndexOf('\"', productName.Length-1) == productName.Length - 1)
productName = productName.Remove(productName.LastIndexOf('\"', productName.Length - 1), 1);
Related
I have code which checks if a word if a palindrome or not. Within the for loop there is a -1 value. Can someone explain to me why -1 is used after the name.Length in c#
public static void Main()
{
string name = "Apple";
string reverse = string.Empty;
for (int i = name.Length - 1; i >= 0; i--)
{
reverse +=name[i];
}
if (name == reverse)
{
Console.WriteLine($"{name} is palindrome");
}else
{
Console.WriteLine($"{name} is not palindrome");
}
That's because whoever wrote the code, wanted to write:
reverse += name[i];
String operator [] takes values from 0 upto (string's length-1). If you pass length or more, you will get an exception. So, code's author had to ensure that i==Length won't be ever passed there. So it starts from Length-1 and counts downwards.
Also, note that the other bound of i is 0 (>=, not >, so 0 is included), so the loop visits all values from 0 to length-1, so it visits all characters from the string. Job done.
However, it doesn't have to be written in that way. The only thing is to ensure that the string operator [] wont see values of of its range. Compare this loop, it's identical in its results:
for (int i = name.Length; i >= 1; i--)
{
reverse += name[i-1];
}
Note that I also changed 0 to 1.
Of course, it's also possible to write a loop with the same effects in a lot of other ways.
The first element in an array is at the index 0 (array[0]). Because the indexing starts at 0 instead of 1 it means that the final element in the array will be at index array.Length-1.
If you had the word and then your array would look like:
name[0] = 'a'
name[1] = 'n'
name[2] = 'd'
the name.Length would equal 3. As you can see, there isn't an element at index 3 in the array so you need to subtract 1 from the length of the array to access the last element.
The for loop in your example starts with the last element in the array (using i as the index). If you tried to set i to i = name.Length then you would get an index out of bounds error because there isn't an element at the position name.Length.
String operator [] takes values from 0. The first element in an string is at the index 0, so we need to adjust by subtracting one.
For Example:
string str = "test";
int length = str.length; //Length of the str is 4. (0 to 3)
I'm making a program which reverses words to sdrow.
I understand that for it to work it needs to be written this way.
I'm more interested on WHY it has to be this way.
Here is my code:
Console.WriteLine("Enter a word : ");
string word = Console.ReadLine();
string rev = "";
int length;
for (length = word.Length - 1; length >= 0; length--)
{
rev = rev + word[length];
}
Console.WriteLine("The reversed word is : {0}", rev);
My questions are:
a) why you must use quotes to initialize your string
b) Why must you start your loop at one less than the total length of your string
c) How arrayname[int] works
I'm pretty new to C# and this site, as well. I hope my questions make sense and that I've asked them in the correct and proper way.
Thank you for your time!
This is how I've interpreted your question.
You want to know why you must use quotes to initialize your string
Why must you start your loop at one less than the total length of your string
How arrayname[int] works
I think that the best way to explain this to you is to go through your code, and explain what it does.
Console.WriteLine("Enter a word : ");
The first line of code prints Enter a word : into the console.
string word = Console.ReadLine();
This line "reads" the input from the console, and puts it into a string called word.
string rev = "";
This initiates a string called rev, setting it's value to "", or an empty string. The other way to initiate the string would be this:
string rev;
That would initiate a string called rev to the value of null. This does not work for your program because rev = rev + word[length]; sets rev to itself + word[length]. It throws an error if it is null.
The next line of your code is:
int length;
That sets an int (which in real life we call an integer, basically a number) to the value of null. That is okay, because it gets set later on without referencing itself.
The next line is a for loop:
for (length = word.Length - 1; length >= 0; length--)
This loop sets an internal variable called length to the current value of word.Length -1. The second item tells how long to run the loop. While the value of length is more than, or equal to 0, the loop will continue to run. The third item generally sets the rate of increase or decrease of your variable. In this case, it is length-- that decreases length by one each time the loop runs.
The next relevant line of code is his:
rev = rev + word[length];
This, as I said before sets rev as itself + the string word at the index of length, whatever number that is at the time.
At the first run through the for loop, rev is set to itself (an empty string), plus the word at the index of length - 1. If the word entered was come (for example), the index 0 would be c, the index 1 would be o, 2 would be m, and 3 = e.
The word length is 4, so that minus one is 3 (yay - back to Kindergarten), which is the last letter in the word.
The second time through the loop, length will be 2, so rev will be itself (e) plus index 2, which is m. This repeats until length hits -1, at which point the loop does not run, and you go on to the next line of code.
...Which is:
Console.WriteLine("The reversed word is : {0}", rev);
This prints a line to the console, saying The reversed word is : <insert value of rev here> The {0} is an internal var set by the stuff after the comma, which in this case would be rev.
The final output of the program, if you inserted come, would look something like this:
>Enter a word :
>come
>
>The reversed word is : emoc
a) you must to initialize or instantiate the variable in order to can work with it. In your case is better to use and StringBuilder, the string are inmutable objects, so each assignement means to recreate a new string.
b) The arrays in C# are zero index based so their indexes go from zero to length -1.
c) An string is an characters array.
Any case maybe you must to try the StringBuilder, it is pretty easy to use
I hope this helps
a) you need to initialize a variable if you want to use it in an assignment rev = rev + word[length];
b) you are using a for loop which means that you define a start number length = word.Length - 1, a stop criteria length >= 0 and a variable change length--
So lenght basically descends from 5 to 0 (makes 6 loops). The reason is that Arrays like 'string' a char[] are zerobased indexed.. means that first element is 0 last is array.Length - 1
c) So a string is basically a chain of char's.. with the []-Operator you can access a single index. The Return Type of words[index] is in this case a character.
I hope it helped
a) You need to first instantiate the string rev before you can assign it values in the loop. You could also say "string rev = String.Empty". You are trying to add word to rev and if you don't tell it first that rev is an empty string it doesn't know what it is adding word to.
b) The characters of the string have indexes to show which position they appear in the string. These indexes start at 0. So you're first character will have an index of 0. If the length of your string is 6 then the last character's index will be 5. So length - 1 will give you the value of the last character's index which is 5. A c# for loop uses the following parameters
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
where "int i = 0;" is the starting index; "i < 10" tells the loop when to stop looping; and "i++" tells it to increment i (the index) after each loop.
So in your code you are saying start at the last character of my string; perform this loop while there are still characters in the string; and decrease the index of the string after each loop so the next loop will look at the previous character in the string.
c) word[length] then in this scenario is saying add the character that has the position with index "length" to the rev string. This will basically reverse the word.
As usual you can do it in linq and avoid the (explicit) loops
using System;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Enter a word : ");
string word = Console.ReadLine();
Console.WriteLine("The reversed word is : {0}", new string (word.Reverse().ToArray()));
Console.ReadLine();
}
}
}
var reversedWords = string.Join(" ",
str.Split(' ')
.Select(x => new String(x.Reverse().ToArray())));
Take a look here :
Easy way to reverse each word in a sentence
I've got a RichTextBox, and would like to highlight a whole word, given just its ending index. Is it possible to highlight from an ending index, backwards to the first occurance of a space?
This is what I've tried so far, but I don't know if there is any other efficient methods:
int length = richTextBox.Text.Reverse().Skip(richTextBox.Text.Length - offset)
.TakeWhile(x => x != ' ')
.Count();
richTextBox.Select(offset - length, length + 1);
richTextBox.SelectionBackColor = Color.Yellow;
That's a very inefficient way to get the length.
Try this- might be off by one somewhere, I cant test it right now:
var prevSpace = richTextBox.Text.LastIndexOf(' ', offset);
var length = prevSpace = -1 ? offset + 1 : offset - prevspace;
I've got a RichTextBox, and would like to highlight a whole word, given just its starting index.
I've been able to highlight a word if the starting index and length is known, however in this case I do not know the length of the word. Is it possible to highlight from a starting index to the first occurance of a space?
UPDATE:
This is what I've tried so far:
resultsRichTextBox.Select(novelOffset - 2, searchString.Length);
Unfortunately 'searchstring' is not always the length of the word being searched for, so I need a way of finding the amount of characters from novelOffset - 2 till the nearest space.
You can do something like this:
int length = this.richTextBox1.Text.Skip(startIdx)
.TakeWhile(x => char.IsLetterOrDigit(x))
.Count();
this.richTextBox1.Select(startIdx, length);
this.richTextBox1.SelectionBackColor = Color.Yellow;
Obviously you can change char.IsLetterOrDigit with x != ' ' or whatever you prefer.
You can use the String.IndexOf(Char, Int32):
Reports the zero-based index of the first occurrence of the specified
Unicode character in this string. The search starts at a specified
character position.
It will give you the starting and end index of your word. You can then highlight it!
int endIndex = resultsRichTextBox.Text.IndexOf(' ', novelOffset - 2);
resultsRichTextBox.Select(novelOffset - 2, (endIndex - (novelOffset - 2)) );
You only need to handle what happens if it doesn't find any space after the word. The endIndex value will be -1 if that happens. I would simply set the value of endIndex to searchString.Length.
int startIndex;
//fill startIndex with the known value
int endIndex = startIndex;
while(rtb.Text.CharAt(endIndex) != ' ' && endIndex < rtb.Text.Length)
{
endIndex++;
}
rtb.Select(startIndex, endIndex);
You can use a Find method given you provide the starting index of the word and look for the SPACE. Find will return you the index of next space and in fact the end of the word (found - 1).
You can then use a select call.
I am taking a line from a file only if that file doen't have a specific pattern.. and i want to take from that line the last 3 chars... my code is:
while (!line.Contains(pattern))
{
String num = line.Substring((line.Length - 3), (line.Length - 2));
System.Console.WriteLine(num);
}
but i get an error..
Index and length must refer to a location within the string.
Parameter name: length
why i get that? i am starting the new string 3 chars before the end of the line and i stop 2 chars before.. :\
Substring takes an offset and then a number of characters to return:
http://msdn.microsoft.com/en-us/library/aa904308%28v=VS.71%29.aspx
So:
String num = line.Substring((line.Length - 3), 3);
This of course assumes that line.Length > 3. You could check with:
String num = (line.Length < 3) ? line : line.Substring((line.Length - 3), 3);
Second argument of Substring is how many chars it have to take starting from first argument. It should just look like that:
String num = line.Substring(line.Length - 3, 3);
This is dangerous. What if the length of the line is < 3? You should probably check this otherwise you will get an exception.
In addition you should use the substring method as depicted here :
String num = line.Substring((line.Length - 3), 3);
The problem is that you try to get more characters then your array have.
Extensions are best for problems like this one ;) Mine have some dirty name but everyone know what it would do - this is exception safe substring:
public static string SubstringNoLongerThenSource(this string source, int startIndex, int maxLength)
{
return source.Substring(startIndex, Math.Min(source.Length - startIndex, maxLength));
}
So in your exact problem it should be like that:
String num = line.SubstringNoLongerThenSource((line.Length - 3), 3);
System.Console.WriteLine(num);
So num will have max 3 letters if the string you provide to function have enough letters :)
String num = line.Substring(line.Length - 3)
This is happening because the last parameter of Substring() should be the length of the string to extract.
In your case it should be 3
, and not line.Length - 2
The first parameter should also be:
line.Length - 3