Related
I have this string: ABCDEFGHIJ
I need to replace from position 4 to position 5 with the string ZX
It will look like this: ABCZXFGHIJ
But not to use with string.replace("DE","ZX") - I need to use with position
How can I do it?
string s = "ABCDEFGH";
s= s.Remove(3, 2).Insert(3, "ZX");
The easiest way to add and remove ranges in a string is to use the StringBuilder.
var theString = "ABCDEFGHIJ";
var aStringBuilder = new StringBuilder(theString);
aStringBuilder.Remove(3, 2);
aStringBuilder.Insert(3, "ZX");
theString = aStringBuilder.ToString();
An alternative is to use String.Substring, but I think the StringBuilder code gets more readable.
ReplaceAt(int index, int length, string replace)
Here's an extension method that doesn't use StringBuilder or Substring. This method also allows the replacement string to extend past the length of the source string.
//// str - the source string
//// index- the start location to replace at (0-based)
//// length - the number of characters to be removed before inserting
//// replace - the string that is replacing characters
public static string ReplaceAt(this string str, int index, int length, string replace)
{
return str.Remove(index, Math.Min(length, str.Length - index))
.Insert(index, replace);
}
When using this function, if you want the entire replacement string to replace as many characters as possible, then set length to the length of the replacement string:
"0123456789".ReplaceAt(7, 5, "Hello") = "0123456Hello"
Otherwise, you can specify the amount of characters that will be removed:
"0123456789".ReplaceAt(2, 2, "Hello") = "01Hello456789"
If you specify the length to be 0, then this function acts just like the insert function:
"0123456789".ReplaceAt(4, 0, "Hello") = "0123Hello456789"
I guess this is more efficient since the StringBuilder class need not be initialized and since it uses more basic operations. Please correct me if I am wrong. :)
If you care about performance, then the thing you want to avoid here are allocations. And if you're on .Net Core 2.1+, then you can, by using the string.Create method:
public static string ReplaceAt(this string str, int index, int length, string replace)
{
return string.Create(str.Length - length + replace.Length, (str, index, length, replace),
(span, state) =>
{
state.str.AsSpan().Slice(0, state.index).CopyTo(span);
state.replace.AsSpan().CopyTo(span.Slice(state.index));
state.str.AsSpan().Slice(state.index + state.length).CopyTo(span.Slice(state.index + state.replace.Length));
});
}
This approach is harder to understand than the alternatives, but it's the only one that will allocate only one object per call: the newly created string.
Use String.Substring() (details here) to cut left part, then your replacement, then right part. Play with indexes until you get it right :)
Something like:
string replacement=original.Substring(0,start)+
rep+original.Substring(start+rep.Length);
string s = "ABCDEFG";
string t = "st";
s = s.Remove(4, t.Length);
s = s.Insert(4, t);
As an extension method.
public static class StringBuilderExtension
{
public static string SubsituteString(this string OriginalStr, int index, int length, string SubsituteStr)
{
return new StringBuilder(OriginalStr).Remove(index, length).Insert(index, SubsituteStr).ToString();
}
}
You could try something link this:
string str = "ABCDEFGHIJ";
str = str.Substring(0, 2) + "ZX" + str.Substring(5);
Like other have mentioned the Substring() function is there for a reason:
static void Main(string[] args)
{
string input = "ABCDEFGHIJ";
string output = input.Overwrite(3, "ZX"); // 4th position has index 3
// ABCZXFGHIJ
}
public static string Overwrite(this string text, int position, string new_text)
{
return text.Substring(0, position) + new_text + text.Substring(position + new_text.Length);
}
Also I timed this against the StringBuilder solution and got 900 tics vs. 875. So it is slightly slower.
Yet another
public static string ReplaceAtPosition(this string self, int position, string newValue)
{
return self.Remove(position, newValue.Length).Insert(position, newValue);
}
With the help of this post, I create following function with additional length checks
public string ReplaceStringByIndex(string original, string replaceWith, int replaceIndex)
{
if (original.Length >= (replaceIndex + replaceWith.Length))
{
StringBuilder rev = new StringBuilder(original);
rev.Remove(replaceIndex, replaceWith.Length);
rev.Insert(replaceIndex, replaceWith);
return rev.ToString();
}
else
{
throw new Exception("Wrong lengths for the operation");
}
}
All others answers don't work if the string contains Unicode char (like Emojis) because an Unicode char weight more bytes than a char.
Example : the emoji '🎶' converted to bytes, will weight the equivalent of 2 chars. So, if the unicode char is placed at the beginning of your string, offset parameter will be shifted).
With this topic, i extend the StringInfo class to Replace by position keeping the Nick Miller's algorithm to avoid that :
public static class StringInfoUtils
{
public static string ReplaceByPosition(this string str, string replaceBy, int offset, int count)
{
return new StringInfo(str).ReplaceByPosition(replaceBy, offset, count).String;
}
public static StringInfo ReplaceByPosition(this StringInfo str, string replaceBy, int offset, int count)
{
return str.RemoveByTextElements(offset, count).InsertByTextElements(offset, replaceBy);
}
public static StringInfo RemoveByTextElements(this StringInfo str, int offset, int count)
{
return new StringInfo(string.Concat(
str.SubstringByTextElements(0, offset),
offset + count < str.LengthInTextElements
? str.SubstringByTextElements(offset + count, str.LengthInTextElements - count - offset)
: ""
));
}
public static StringInfo InsertByTextElements(this StringInfo str, int offset, string insertStr)
{
if (string.IsNullOrEmpty(str?.String))
return new StringInfo(insertStr);
return new StringInfo(string.Concat(
str.SubstringByTextElements(0, offset),
insertStr,
str.LengthInTextElements - offset > 0 ? str.SubstringByTextElements(offset, str.LengthInTextElements - offset) : ""
));
}
}
string myString = "ABCDEFGHIJ";
string modifiedString = new StringBuilder(myString){[3]='Z', [4]='X'}.ToString();
Let me explain my solution.
Given the problem statement of altering a string in its two specific position (“position 4 to position 5”) with two character ‘Z’ and ‘X’ and the ask is to use the position index to alter the string and not string Replace() method(may be because of the possibility of repetition of some characters in the actual string), I would prefer to use minimalist approach to achieve the goal over using Substring() and string Concat() or string Remove() and Insert() approach. Though all those solutions will serve the purpose in attaining the same goal, but it just depends on personal choice and philosophy of settling with minimalist approach.
Coming back to my solution mention above, if we take a closer look of string and StringBuilder, both of them internally treats a given string as an array of characters. If we look at the implementation of StringBuilder it maintains an internal variable something like “internal char[] m_ChunkChars;” to capture the given string. Now since this is an internal variable, we cannot directly access the same. For external world, to be able to access and alter that character array, StringBuilder exposes them through indexer property which looks something like below
[IndexerName("Chars")]
public char this[int index]
{
get
{
StringBuilder stringBuilder = this;
do
{
// … some code
return stringBuilder.m_ChunkChars[index1];
// … some more code
}
}
set
{
StringBuilder stringBuilder = this;
do
{
//… some code
stringBuilder.m_ChunkChars[index1] = value;
return;
// …. Some more code
}
}
}
My solution mentioned above leverage this indexer capability to directly alter the internally maintained character array which IMO is efficient and minimalist.
BTW; we can rewrite the above solution more elaborately something like below
string myString = "ABCDEFGHIJ";
StringBuilder tempString = new StringBuilder(myString);
tempString[3] = 'Z';
tempString[4] = 'X';
string modifiedString = tempString.ToString();
In this context also would like to mention that in case of string it also have indexer property as a means to expose its internal character array, but in this case it only has Getter property (and no Setter) as string is immutable in nature. And that is why we need to use StringBuilder to alter the character array.
[IndexerName("Chars")]
public extern char this[int index] { [SecuritySafeCritical, __DynamicallyInvokable, MethodImpl(MethodImplOptions.InternalCall)] get; }
And last but not the least this solution is only best fit for this specific problem where the ask is to replace only few characters with a known position index upfront. It may not be the best fit when the requirement is to alter a fairly lengthy string i.e. number of characters to alter are large in numbers.
I was looking for a solution with following requirements:
use only a single, one-line expression
use only system builtin methods (no custom implemented utility)
Solution 1
The solution that best suits me is this:
// replace `oldString[i]` with `c`
string newString = new StringBuilder(oldString).Replace(oldString[i], c, i, 1).ToString();
This uses StringBuilder.Replace(oldChar, newChar, position, count)
Solution 2
The other solution that satisfies my requirements is to use Substring with concatenation:
string newString = oldStr.Substring(0, i) + c + oldString.Substring(i+1, oldString.Length);
This is OK too. I guess it's not as efficient as the first one performance wise (due to unnecessary string concatenation). But premature optimization is the root of all evil.
So pick the one that you like the most :)
hello this code helps me:
var theString = "ABCDEFGHIJ";
var aStringBuilder = new StringBuilder(theString);
aStringBuilder.Remove(3, 2);
aStringBuilder.Insert(3, "ZX");
theString = aStringBuilder.ToString();
It's better to use the String.substr().
Like this:
ReplString = GivenStr.substr(0, PostostarRelStr)
+ GivenStr(PostostarRelStr, ReplString.lenght());
String timestamp = "2019-09-18 21.42.05.000705";
String sub1 = timestamp.substring(0, 19).replace('.', ':');
String sub2 = timestamp.substring(19, timestamp.length());
System.out.println("Original String "+ timestamp);
System.out.println("Replaced Value "+ sub1+sub2);
Here is a simple extension method:
public static class StringBuilderExtensions
{
public static StringBuilder Replace(this StringBuilder sb, int position, string newString)
=> sb.Replace(position, newString.Length, newString);
public static StringBuilder Replace(this StringBuilder sb, int position, int length, string newString)
=> (newString.Length <= length)
? sb.Remove(position, newString.Length).Insert(position, newString)
: sb.Remove(position, length).Insert(position, newString.Substring(0, length));
}
Use it like this:
var theString = new string(' ', 10);
var sb = new StringBuilder(theString);
sb.Replace(5, "foo");
return sb.ToString();
I do this
Dim QTT As Double
If IsDBNull(dr.Item(7)) Then
QTT = 0
Else
Dim value As String = dr.Item(7).ToString()
Dim posicpoint As Integer = value.LastIndexOf(".")
If posicpoint > 0 Then
Dim v As New Text.StringBuilder(value)
v.Remove(posicpoint, 1)
v.Insert(posicpoint, ",")
QTT = Convert.ToDouble(v.ToString())
Else
QTT = Convert.ToDouble(dr.Item(7).ToString())
End If
Console.WriteLine(QTT.ToString())
End If
Suppose we know the index of string to be replace.
string s = "ABCDEFGDEJ";
string z = "DE";
int i = s.IndexOf(z);
if(i == 3)
s = s.Remove(3,z.Length).Insert(3,"ZX");
//s = ABCZXFGDEJ
I believe the simplest way would be this:(without stringbuilder)
string myString = "ABCDEFGHIJ";
char[] replacementChars = {'Z', 'X'};
byte j = 0;
for (byte i = 3; i <= 4; i++, j++)
{
myString = myString.Replace(myString[i], replacementChars[j]);
}
This works because a variable of type string can be treated as an array of char variables.
You can, for example refer to the second character of a string variable with name "myString" as myString[1]
I have a string as follows:
string str = "abcdefgh"
and I would like to reduce the size to only two chars - so the output would be:
str = "ab"
string str = "abcdefgh";
var s = str.Substring(0, 2);
Or another solution is to write Your Own extension method (that would check if string longer than expected substring and avoid the exception as athoik has noticed) and do this
class Program
{
static void Main(string[] args)
{
var str = "asdfasd";
var trimmed = str.MySubString(2);
Console.WriteLine(trimmed);
Console.ReadLine();
}
}
public static class Helper
{
public static string MySubString(this String value, int length)
{
return !string.IsNullOrEmpty(value) && value.Length >= length
? value.Substring(0, length)
: value;
}
}
string sub = str.Substring(0, 2);
string substr = str.substring(0,2)
or
StringBuilder sb = new StringBuilder();
sb.toString(0,2);
I have this string: ABCDEFGHIJ
I need to replace from position 4 to position 5 with the string ZX
It will look like this: ABCZXFGHIJ
But not to use with string.replace("DE","ZX") - I need to use with position
How can I do it?
string s = "ABCDEFGH";
s= s.Remove(3, 2).Insert(3, "ZX");
The easiest way to add and remove ranges in a string is to use the StringBuilder.
var theString = "ABCDEFGHIJ";
var aStringBuilder = new StringBuilder(theString);
aStringBuilder.Remove(3, 2);
aStringBuilder.Insert(3, "ZX");
theString = aStringBuilder.ToString();
An alternative is to use String.Substring, but I think the StringBuilder code gets more readable.
ReplaceAt(int index, int length, string replace)
Here's an extension method that doesn't use StringBuilder or Substring. This method also allows the replacement string to extend past the length of the source string.
//// str - the source string
//// index- the start location to replace at (0-based)
//// length - the number of characters to be removed before inserting
//// replace - the string that is replacing characters
public static string ReplaceAt(this string str, int index, int length, string replace)
{
return str.Remove(index, Math.Min(length, str.Length - index))
.Insert(index, replace);
}
When using this function, if you want the entire replacement string to replace as many characters as possible, then set length to the length of the replacement string:
"0123456789".ReplaceAt(7, 5, "Hello") = "0123456Hello"
Otherwise, you can specify the amount of characters that will be removed:
"0123456789".ReplaceAt(2, 2, "Hello") = "01Hello456789"
If you specify the length to be 0, then this function acts just like the insert function:
"0123456789".ReplaceAt(4, 0, "Hello") = "0123Hello456789"
I guess this is more efficient since the StringBuilder class need not be initialized and since it uses more basic operations. Please correct me if I am wrong. :)
If you care about performance, then the thing you want to avoid here are allocations. And if you're on .Net Core 2.1+, then you can, by using the string.Create method:
public static string ReplaceAt(this string str, int index, int length, string replace)
{
return string.Create(str.Length - length + replace.Length, (str, index, length, replace),
(span, state) =>
{
state.str.AsSpan().Slice(0, state.index).CopyTo(span);
state.replace.AsSpan().CopyTo(span.Slice(state.index));
state.str.AsSpan().Slice(state.index + state.length).CopyTo(span.Slice(state.index + state.replace.Length));
});
}
This approach is harder to understand than the alternatives, but it's the only one that will allocate only one object per call: the newly created string.
Use String.Substring() (details here) to cut left part, then your replacement, then right part. Play with indexes until you get it right :)
Something like:
string replacement=original.Substring(0,start)+
rep+original.Substring(start+rep.Length);
string s = "ABCDEFG";
string t = "st";
s = s.Remove(4, t.Length);
s = s.Insert(4, t);
As an extension method.
public static class StringBuilderExtension
{
public static string SubsituteString(this string OriginalStr, int index, int length, string SubsituteStr)
{
return new StringBuilder(OriginalStr).Remove(index, length).Insert(index, SubsituteStr).ToString();
}
}
You could try something link this:
string str = "ABCDEFGHIJ";
str = str.Substring(0, 2) + "ZX" + str.Substring(5);
Like other have mentioned the Substring() function is there for a reason:
static void Main(string[] args)
{
string input = "ABCDEFGHIJ";
string output = input.Overwrite(3, "ZX"); // 4th position has index 3
// ABCZXFGHIJ
}
public static string Overwrite(this string text, int position, string new_text)
{
return text.Substring(0, position) + new_text + text.Substring(position + new_text.Length);
}
Also I timed this against the StringBuilder solution and got 900 tics vs. 875. So it is slightly slower.
Yet another
public static string ReplaceAtPosition(this string self, int position, string newValue)
{
return self.Remove(position, newValue.Length).Insert(position, newValue);
}
With the help of this post, I create following function with additional length checks
public string ReplaceStringByIndex(string original, string replaceWith, int replaceIndex)
{
if (original.Length >= (replaceIndex + replaceWith.Length))
{
StringBuilder rev = new StringBuilder(original);
rev.Remove(replaceIndex, replaceWith.Length);
rev.Insert(replaceIndex, replaceWith);
return rev.ToString();
}
else
{
throw new Exception("Wrong lengths for the operation");
}
}
All others answers don't work if the string contains Unicode char (like Emojis) because an Unicode char weight more bytes than a char.
Example : the emoji '🎶' converted to bytes, will weight the equivalent of 2 chars. So, if the unicode char is placed at the beginning of your string, offset parameter will be shifted).
With this topic, i extend the StringInfo class to Replace by position keeping the Nick Miller's algorithm to avoid that :
public static class StringInfoUtils
{
public static string ReplaceByPosition(this string str, string replaceBy, int offset, int count)
{
return new StringInfo(str).ReplaceByPosition(replaceBy, offset, count).String;
}
public static StringInfo ReplaceByPosition(this StringInfo str, string replaceBy, int offset, int count)
{
return str.RemoveByTextElements(offset, count).InsertByTextElements(offset, replaceBy);
}
public static StringInfo RemoveByTextElements(this StringInfo str, int offset, int count)
{
return new StringInfo(string.Concat(
str.SubstringByTextElements(0, offset),
offset + count < str.LengthInTextElements
? str.SubstringByTextElements(offset + count, str.LengthInTextElements - count - offset)
: ""
));
}
public static StringInfo InsertByTextElements(this StringInfo str, int offset, string insertStr)
{
if (string.IsNullOrEmpty(str?.String))
return new StringInfo(insertStr);
return new StringInfo(string.Concat(
str.SubstringByTextElements(0, offset),
insertStr,
str.LengthInTextElements - offset > 0 ? str.SubstringByTextElements(offset, str.LengthInTextElements - offset) : ""
));
}
}
string myString = "ABCDEFGHIJ";
string modifiedString = new StringBuilder(myString){[3]='Z', [4]='X'}.ToString();
Let me explain my solution.
Given the problem statement of altering a string in its two specific position (“position 4 to position 5”) with two character ‘Z’ and ‘X’ and the ask is to use the position index to alter the string and not string Replace() method(may be because of the possibility of repetition of some characters in the actual string), I would prefer to use minimalist approach to achieve the goal over using Substring() and string Concat() or string Remove() and Insert() approach. Though all those solutions will serve the purpose in attaining the same goal, but it just depends on personal choice and philosophy of settling with minimalist approach.
Coming back to my solution mention above, if we take a closer look of string and StringBuilder, both of them internally treats a given string as an array of characters. If we look at the implementation of StringBuilder it maintains an internal variable something like “internal char[] m_ChunkChars;” to capture the given string. Now since this is an internal variable, we cannot directly access the same. For external world, to be able to access and alter that character array, StringBuilder exposes them through indexer property which looks something like below
[IndexerName("Chars")]
public char this[int index]
{
get
{
StringBuilder stringBuilder = this;
do
{
// … some code
return stringBuilder.m_ChunkChars[index1];
// … some more code
}
}
set
{
StringBuilder stringBuilder = this;
do
{
//… some code
stringBuilder.m_ChunkChars[index1] = value;
return;
// …. Some more code
}
}
}
My solution mentioned above leverage this indexer capability to directly alter the internally maintained character array which IMO is efficient and minimalist.
BTW; we can rewrite the above solution more elaborately something like below
string myString = "ABCDEFGHIJ";
StringBuilder tempString = new StringBuilder(myString);
tempString[3] = 'Z';
tempString[4] = 'X';
string modifiedString = tempString.ToString();
In this context also would like to mention that in case of string it also have indexer property as a means to expose its internal character array, but in this case it only has Getter property (and no Setter) as string is immutable in nature. And that is why we need to use StringBuilder to alter the character array.
[IndexerName("Chars")]
public extern char this[int index] { [SecuritySafeCritical, __DynamicallyInvokable, MethodImpl(MethodImplOptions.InternalCall)] get; }
And last but not the least this solution is only best fit for this specific problem where the ask is to replace only few characters with a known position index upfront. It may not be the best fit when the requirement is to alter a fairly lengthy string i.e. number of characters to alter are large in numbers.
I was looking for a solution with following requirements:
use only a single, one-line expression
use only system builtin methods (no custom implemented utility)
Solution 1
The solution that best suits me is this:
// replace `oldString[i]` with `c`
string newString = new StringBuilder(oldString).Replace(oldString[i], c, i, 1).ToString();
This uses StringBuilder.Replace(oldChar, newChar, position, count)
Solution 2
The other solution that satisfies my requirements is to use Substring with concatenation:
string newString = oldStr.Substring(0, i) + c + oldString.Substring(i+1, oldString.Length);
This is OK too. I guess it's not as efficient as the first one performance wise (due to unnecessary string concatenation). But premature optimization is the root of all evil.
So pick the one that you like the most :)
hello this code helps me:
var theString = "ABCDEFGHIJ";
var aStringBuilder = new StringBuilder(theString);
aStringBuilder.Remove(3, 2);
aStringBuilder.Insert(3, "ZX");
theString = aStringBuilder.ToString();
It's better to use the String.substr().
Like this:
ReplString = GivenStr.substr(0, PostostarRelStr)
+ GivenStr(PostostarRelStr, ReplString.lenght());
String timestamp = "2019-09-18 21.42.05.000705";
String sub1 = timestamp.substring(0, 19).replace('.', ':');
String sub2 = timestamp.substring(19, timestamp.length());
System.out.println("Original String "+ timestamp);
System.out.println("Replaced Value "+ sub1+sub2);
Here is a simple extension method:
public static class StringBuilderExtensions
{
public static StringBuilder Replace(this StringBuilder sb, int position, string newString)
=> sb.Replace(position, newString.Length, newString);
public static StringBuilder Replace(this StringBuilder sb, int position, int length, string newString)
=> (newString.Length <= length)
? sb.Remove(position, newString.Length).Insert(position, newString)
: sb.Remove(position, length).Insert(position, newString.Substring(0, length));
}
Use it like this:
var theString = new string(' ', 10);
var sb = new StringBuilder(theString);
sb.Replace(5, "foo");
return sb.ToString();
I do this
Dim QTT As Double
If IsDBNull(dr.Item(7)) Then
QTT = 0
Else
Dim value As String = dr.Item(7).ToString()
Dim posicpoint As Integer = value.LastIndexOf(".")
If posicpoint > 0 Then
Dim v As New Text.StringBuilder(value)
v.Remove(posicpoint, 1)
v.Insert(posicpoint, ",")
QTT = Convert.ToDouble(v.ToString())
Else
QTT = Convert.ToDouble(dr.Item(7).ToString())
End If
Console.WriteLine(QTT.ToString())
End If
Suppose we know the index of string to be replace.
string s = "ABCDEFGDEJ";
string z = "DE";
int i = s.IndexOf(z);
if(i == 3)
s = s.Remove(3,z.Length).Insert(3,"ZX");
//s = ABCZXFGDEJ
I believe the simplest way would be this:(without stringbuilder)
string myString = "ABCDEFGHIJ";
char[] replacementChars = {'Z', 'X'};
byte j = 0;
for (byte i = 3; i <= 4; i++, j++)
{
myString = myString.Replace(myString[i], replacementChars[j]);
}
This works because a variable of type string can be treated as an array of char variables.
You can, for example refer to the second character of a string variable with name "myString" as myString[1]
How can I convert an int datatype into a string datatype in C#?
string myString = myInt.ToString();
string a = i.ToString();
string b = Convert.ToString(i);
string c = string.Format("{0}", i);
string d = $"{i}";
string e = "" + i;
string f = string.Empty + i;
string g = new StringBuilder().Append(i).ToString();
Just in case you want the binary representation and you're still drunk from last night's party:
private static string ByteToString(int value)
{
StringBuilder builder = new StringBuilder(sizeof(byte) * 8);
BitArray[] bitArrays = BitConverter.GetBytes(value).Reverse().Select(b => new BitArray(new []{b})).ToArray();
foreach (bool bit in bitArrays.SelectMany(bitArray => bitArray.Cast<bool>().Reverse()))
{
builder.Append(bit ? '1' : '0');
}
return builder.ToString();
}
Note: Something about not handling endianness very nicely...
If you don't mind sacrificing a bit of memory for speed, you can use below to generate an array with pre-calculated string values:
static void OutputIntegerStringRepresentations()
{
Console.WriteLine("private static string[] integerAsDecimal = new [] {");
for (int i = int.MinValue; i < int.MaxValue; i++)
{
Console.WriteLine("\t\"{0}\",", i);
}
Console.WriteLine("\t\"{0}\"", int.MaxValue);
Console.WriteLine("}");
}
int num = 10;
string str = Convert.ToString(num);
The ToString method of any object is supposed to return a string representation of that object.
int var1 = 2;
string var2 = var1.ToString();
Further on to #Xavier's response, here's a page that does speed comparisons between several different ways to do the conversion from 100 iterations up to 21,474,836 iterations.
It seems pretty much a tie between:
int someInt = 0;
someInt.ToString(); //this was fastest half the time
//and
Convert.ToString(someInt); //this was the fastest the other half the time
string str = intVar.ToString();
In some conditions, you do not have to use ToString()
string str = "hi " + intVar;
or:
string s = Convert.ToString(num);
using System.ComponentModel;
TypeConverter converter = TypeDescriptor.GetConverter(typeof(int));
string s = (string)converter.ConvertTo(i, typeof(string));
None of the answers mentioned that the ToString() method can be applied to integer expressions
Debug.Assert((1000*1000).ToString()=="1000000");
even to integer literals
Debug.Assert(256.ToString("X")=="100");
Although integer literals like this are often considered to be bad coding style (magic numbers) there may be cases where this feature is useful...
string s = "" + 2;
and you can do nice things like:
string s = 2 + 2 + "you"
The result will be:
"4 you"
if you're getting from a dataset
string newbranchcode = (Convert.ToInt32(ds.Tables[0].Rows[0]["MAX(BRANCH_CODE)"]) ).ToString();
What's the cleanest way of editing the characters in a string in C#?
What's the C# equivalent of this in C++:
std::string myString = "boom";
myString[0] = "d";
Use a StringBuilder instead.
string is immutable as described by MSDN:
Strings are immutable--the contents of
a string object cannot be changed
after the object is created, although
the syntax makes it appear as if you
can do this.
So you want something like:
StringBuilder sb = new StringBuilder("Bello World!");
sb[0] = 'H';
string str = sb.ToString();
Decided to time what I felt where the two most canonical approaches, plus one I threw in as unrepresented; here's what I found (Release build):
ReplaceAtChars: 86ms
ReplaceAtSubstring: 258ms
ReplaceAtStringBuilder: 161ms
Clearly the Char array approach is by far best optimized by the runtime. Which actually suggests that the current leading answer (StringBuilder) is likely not the best answer.
And here was the test I used:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("ReplaceAtChars: " + new Stopwatch().Time(() => "test".ReplaceAtChars(1, 'E').ReplaceAtChars(3, 'T'), 1000000) + "ms");
Console.WriteLine("ReplaceAtSubstring: " + new Stopwatch().Time(() => "test".ReplaceAtSubstring(1, 'E').ReplaceAtSubstring(3, 'T'), 1000000) + "ms");
Console.WriteLine("ReplaceAtStringBuilder: " + new Stopwatch().Time(() => "test".ReplaceAtStringBuilder(1, 'E').ReplaceAtStringBuilder(3, 'T'), 1000000) + "ms");
}
}
public static class ReplaceAtExtensions
{
public static string ReplaceAtChars(this string source, int index, char replacement)
{
var temp = source.ToCharArray();
temp[index] = replacement;
return new String(temp);
}
public static string ReplaceAtStringBuilder(this string source, int index, char replacement)
{
var sb = new StringBuilder(source);
sb[index] = replacement;
return sb.ToString();
}
public static string ReplaceAtSubstring(this string source, int index, char replacement)
{
return source.Substring(0, index) + replacement + source.Substring(index + 1);
}
}
public static class StopwatchExtensions
{
public static long Time(this Stopwatch sw, Action action, int iterations)
{
sw.Reset();
sw.Start();
for (int i = 0; i < iterations; i++)
{
action();
}
sw.Stop();
return sw.ElapsedMilliseconds;
}
}
Strings in .Net are immutable. That means you can't edit them. All you can do is make new ones. You have to do something like this:
string myString = "boom";
myString = "d" + myString.Substring(1);
Strings are immutable, so you can't just change it.
You could get a char[] from the string, make your changes, and make a new string from the altered array.
You could use things like replace, although they don't give you control over the per-char basis as C like. They also will make a new string with every change, where the char[] style allows you to make all changes and then make a new string from it.
You can't since strings are immutable.
You could always roll your own extension method to do something similar:
public static string ReplaceAtIndex(this string original,
int index, char character)
{
char[] temp = original.ToCharArray();
temp[index] = character;
return new String(temp);
}
And call it like:
string newString = myString.ReplaceAtIndex(0, 'd');
As Brian said, use a StringBuilder, instead:
string myString = "boom";
StringBuilder myStringBuilder = new StringBuilder(myString);
myStringBuilder[0] = 'd';
// Whatever else you're going to do to it
Whenever you need the string again, call myStringBuilder.ToString()
string myString = "boom";
char[] arr = myString.ToCharArray();
arr[0] = 'd';
myString = new String(arr);
string myString = "boom";
char[] myChars = myString.ToCharArray();
myChars[0] = 'd';
myString = new String(myChars);
Strings are immutable in C#. Use the StringBuilder class or a character array.
StringBuilder sb = new StringBuilder("boom");
sb[0] = 'd';
IIRC, .NET uses what is called String Pooling. Every time a new string literal is created, it is stored in memory as part of the string pool. If you create a second string that matches a string in the string pool, both variables will reference the same memory.
When you try to do an operation like you did to replace the 'b' character with a 'd' character using strings in .NET, your program is actually creating a second string in the string pool with the value "doom", although from your perspective it does not appear as if this is happening at all. By reading the code, one would assume that the character is being replaced.
I brought this up because I encounter this question all the time, and people often ask why they should be using the StringBuilder when a string can do the same thing. Well technically it can't, but it's designed in a way to appear as if it can.
Here's a fun one I put together. Now, please bear in mind this is not very efficient, especially for simple replacements. However, it was fun to write and lends itself to a fairly readable usage pattern. It also highlights the little known fact that String implements IEnumerable.
public static class LinqToStrings
{
public static IQueryable<char> LinqReplace(this string source, int startIndex, int length, string replacement)
{
var querySource = source.AsQueryable();
return querySource.LinqReplace(startIndex, length, replacement);
}
public static IQueryable<char> LinqReplace(this IQueryable<char> source, int startIndex, int length, string replacement)
{
var querySource = source.AsQueryable();
return querySource.Take(startIndex).Concat(replacement).Concat(querySource.Skip(startIndex + length));
}
public static string AsString(this IQueryable<char> source)
{
return new string(source.ToArray());
}
}
And here's some example usage:
public void test()
{
var test = "test";
Console.WriteLine("Old: " + test);
Console.WriteLine("New: " + test.LinqReplace(0, 4, "SOMEPIG")
.LinqReplace(4, 0, "terrific")
.AsString());
}
Outputs:
Old: test
New: SOMEterrificPIG
Another version of that same approach, which is not so horrifically slow is straightforward using Substring:
public static string ReplaceAt(this string source, int startIndex, int length, string replacement)
{
return source.Substring(0, startIndex) + replacement + source.Substring(startIndex + length);
}
And in a wonderful example of why you should profile your code, and why you probably should not use my LinqToStrings implementation in production code, here's a timing test:
Console.WriteLine("Using LinqToStrings: " + new Stopwatch().Time(() => "test".LinqReplace(0, 4, "SOMEPIG").LinqReplace(4, 0, "terrific").AsString(), 1000));
Console.WriteLine("Using Substrings: " + new Stopwatch().Time(() => "test".ReplaceAt(0, 4, "SOMEPIG").ReplaceAt(4, 0, "terrific"), 1000));
Which measures timer ticks in 1,000 iterations, producing this output:
Using LinqToStrings: 3,818,953
Using Substrings: 1,157
Try using string.replace
http://msdn.microsoft.com/en-us/library/fk49wtc1.aspx
Probably your cleanest, easiest way.