I've been looking around and it seems like I'm using this properly, but the results are failing. I want to go through and get rid of any 0's and replace them with o's.
newString = strOld.Replace('0', 'o'); // doesn't work.
newString = strOld.Replace("0", "o"); // doesn't work either.
Am I doing something wrong?
I made this test, and it works fine:
class Program
{
static void Main(string[] args)
{
var newString = "M0000".Replace('0', 'o');
}
}
Try a small test case, similar to the one I created, and see what happens.
Turns out in order to use the replace method it had to go into the same string. So while this won't work:
String newString;
String oldString = "b00k";
newString = oldString.Replace('0', 'o');
This will work:
String newString = "b00k";
newString = newString.Replace('0', 'o');
Appreciate all the feedback.
I was facing the same problem, actually just for information, I was doing something thing like myOldString.Replace("#", "No.");.
It was not working, I checked it.
Finally I found the solution, when i replaced the above string as
myOldString = myOldString.Replace("#","No");
string.replace makes a replica, earlier i was not assigning that to the actual string.
Make sure you are not making such t
Works fine here... the char version should work regardless of case if they were letters (I assume you're trying to replace zeroes with an lowercase O). Are you maybe using a font that does not distinguish between zero and the letter O or something like that?
You're not doing anything wrong. If you want to do a character replace instead of a string replace you need to do: s.Replace(char.Parse("0"), char.Parse("o")), but I can't think of any reason your code doesn't work.
The following link shows this very clearly: http://www.dotnetperls.com/replace
If you use string.Replace, it has to be assigned (as mentioned above by Geeklat):
String newString = "b00k";
newString = newString.Replace('0', 'o');
If you use "StringBuilder" the variable not have to be assigned -
Here is a Sample Program (Output is below):
using System;
using System.Text;
class Program
{
static void Main()
{
const string s = "This is an example.";
// A
// Create new StringBuilder from string
StringBuilder b = new StringBuilder(s);
Console.WriteLine(b);
// B
// Replace the first word
// The result doesn't need assignment
b.Replace("This", "Here");
Console.WriteLine(b);
// C
// Insert the string at the beginning
b.Insert(0, "Sentence: ");
Console.WriteLine(b);
}
}
Output:
This is an example.
Here is an example.
Sentence: Here is an example.
Related
I am creating a console application upon which the user can type in a train station and find the train stations. For this, I am appending the Console.ReadKey().Key to a String each time.
When the user types an incorrect letter, I want the ConsoleKey.Backspace to remove the last Char in the String.
private void SetDepartingFrom()
{
String searchQuery = "";
ConsoleKey keyIn;
while ((keyIn = readKey(searchQuery)) != ConsoleKey.Enter)
{
if (keyIn == ConsoleKey.Backspace)
{
searchQuery.TrimEnd(searchQuery[searchQuery.Length - 1]);
}
else
{
searchQuery += keyIn.ToString();
}
}
}
private ConsoleKey readKey(String searchQuery)
{
Console.Clear();
Console.WriteLine("Stations Found:");
if (searchQuery != "")
App.Stations.FindAll(x => x.GetName().ToUpper().Contains(searchQuery.ToUpper())).ForEach(x => Console.WriteLine(x.GetName()));
else
Console.WriteLine("No Stations found...");
Console.Write("Search: " + searchQuery);
return Console.ReadKey().Key;
}
I have tried the following:
if (keyIn == ConsoleKey.Backspace)
searchQuery.TrimEnd(searchQuery[searchQuery.Length - 1]);
if (keyIn == ConsoleKey.Backspace)
searchQuery.Remove(searchQuery.Length -1);
if (keyIn == ConsoleKey.Backspace)
searchQuery[searchQuery.Length -1] = "";
None have worked. I understand Strings are immutable in C#, however, is this possible or is there a better way to achieve this?
Thanks in advance.
String is immutable so you have to use the value returned by TrimEnd.
searchQuery = searchQuery.TrimEnd(searchQuery[searchQuery.Length - 1]);
In this case I think Substring method would be more appropriate.
As you noted, strings are immutable. All of the instance methods on the string type (at least those related to "modifying" it) return a new string. This means that calling something like the following returns a new string which is immediately discarded:
// value is discarded
searchQuery.Substring(0, searchQuery.Length - 1);
The solution is to reassign the variable with the new value. For example:
searchQuery = searchQuery.Substring(0, searchQuery.Length - 1);
SharpLab example
If you are using C# 8 you can make use of the range operator via the Index/Range classes. This provides a bit cleaner version:
// backspace one character
searchQuery = searchQuery[..^1];
SharpLab example
I will also note that TrimEnd is most likely not what you want. It will trim more than one character at a time which isn't what a single press of the Backspace key would do. For example consider the following:
var str = "Abcdeee";
var result = str.TrimEnd('e');
Console.WriteLine(result); // prints "Abcd"
SharpLab example
Any method you use to manipulate the string will return the new string so you need to capture that.
string newString = searchQuery.Substring(0, searchQuery.Length -1);
It will return a new string, so you need to assign it to a string like this.
string newStr = earchQuery.Remove(searchQuery.Length -1);
Or to same string you can do like this.
earchQuery= earchQuery.Remove(searchQuery.Length -1);
You can also use TrimEnd and SubString methods.
You may try the following code example which removes the last character from a string.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
string founder = "Hell World from Big_Data_Analyst!";
string founderMinus1 = founder.Remove(founder.Length - 1, 1);
Console.WriteLine(founderMinus1);
}
}
}
The input string in the code is
Hell World from Big_Data_Analyst!
The output string is
Hell World from Big_Data_Analyst
As you see the last character which is ! is being removed in the output
I need to process a numeral as a string.
My value is 0x28 and this is the ascii code for '('.
I need to assign this to a string.
The following lines do this.
char c = (char)0x28;
string s = c.ToString();
string s2 = ((char)0x28).ToString();
My usecase is a function that only accepts strings.
My call ends up looking cluttered:
someCall( ((char)0x28).ToString() );
Is there a way of simplifying this and make it more readable without writing '(' ?
The Hexnumber in the code is always paired with a Variable that contains that hex value in its name, so "translating" it would destroy that visible connection.
Edit:
A List of tuples is initialised with this where the first item has the character in its name and the second item results from a call with that character.
One of the answers below is exactly what i am looking for so i incorporated it here now.
{ existingStaticVar0x28, someCall("\u0028") }
The reader can now instinctively see the connection between item1 and item2 and is less likely to run into a trap when this gets refactored.
You can use Unicode character escape sequence in place of a hex to avoid casting:
string s2 = '\u28'.ToString();
or
someCall("\u28");
Well supposing that you have not a fixed input then you could write an extension method
namespace MyExtensions
{
public static class MyStringExtensions
{
public static string ConvertFromHex(this string hexData)
{
int c = Convert.ToInt32(hexCode, 16);
return new string(new char[] {(char)c});
}
}
}
Now you could call it in your code wjth
string hexNumber = "0x28"; // or whatever hexcode you need to convert
string result = hexNumber.ConvertFromHex();
A bit of error handling should be added to the above conversion.
I've been using C# String.Format for formatting numbers before like this (in this example I simply want to insert a space):
String.Format("{0:### ###}", 123456);
output:
"123 456"
In this particular case, the number is a string. My first thought was to simply parse it to a number, but it makes no sense in the context, and there must be a prettier way.
Following does not work, as ## looks for numbers
String.Format("{0:### ###}", "123456");
output:
"123456"
What is the string equivalent to # when formatting? The awesomeness of String.Format is still fairly new to me.
You have to parse the string to a number first.
int number = int.Parse("123456");
String.Format("{0:### ###}", number);
of course you could also use string methods but that's not as reliable and less safe:
string strNumber = "123456";
String.Format("{0} {1}", strNumber.Remove(3), strNumber.Substring(3));
As Heinzi pointed out, you can not have format specifier for string arguments.
So, instead of String.Format, you may use following:
string myNum="123456";
myNum=myNum.Insert(3," ");
Not very beautiful, and the extra work might outweigh the gains, but if the input is a string on that format, you could do:
var str = "123456";
var result = String.Format("{0} {1}", str.Substring(0,3), str.Substring(3));
string is not a IFormattable
Console.WriteLine("123456" is IFormattable); // False
Console.WriteLine(21321 is IFormattable); // True
No point to supply a format if the argument is not IFormattable only way is to convert your string to int or long
We're doing string manipulation, so we could always use a regex.
Adapted slightly from here:
class MyClass
{
static void Main(string[] args)
{
string sInput, sRegex;
// The string to search.
sInput = "123456789";
// The regular expression.
sRegex = "[0-9][0-9][0-9]";
Regex r = new Regex(sRegex);
MyClass c = new MyClass();
// Assign the replace method to the MatchEvaluator delegate.
MatchEvaluator myEvaluator = new MatchEvaluator(c.ReplaceNums);
// Replace matched characters using the delegate method.
sInput = r.Replace(sInput, myEvaluator);
// Write out the modified string.
Console.WriteLine(sInput);
}
public string ReplaceNums(Match m)
// Replace each Regex match with match + " "
{
return m.ToString()+" ";
}
}
How's that?
It's been ages since I used C# and I can't test, but this may work as a one-liner which may be "neater" if you only need it once:
sInput = Regex("[0-9][0-9][0-9]").Replace(sInput,MatchEvaluator(Match m => m.ToString()+" "));
There is no way to do what you want unless you parse the string first.
Based on your comments, you only really need a simple formatting so you are better off just implementing a small helper method and thats it. (IMHO it's not really a good idea to parse the string if it isn't logically a number; you can't really be sure that in the future the input string might not be a number at all.
I'd go for something similar to:
public static string Group(this string s, int groupSize = 3, char groupSeparator = ' ')
{
var formattedIdentifierBuilder = new StringBuilder();
for (int i = 0; i < s.Length; i++)
{
if (i != 0 && (s.Length - i) % groupSize == 0)
{
formattedIdentifierBuilder.Append(groupSeparator);
}
formattedIdentifierBuilder.Append(s[i]);
}
return formattedIdentifierBuilder.ToString();
}
EDIT: Generalized to generic grouping size and group separator.
The problem is that # is a Digit placeholder and it is specific to numeric formatting only. Hence, you can't use this on strings.
Either parse the string to a numeric, so the formatting rules apply, or use other methods to split the string in two.
string.Format("{0:### ###}", int.Parse("123456"));
I have the below code:
sDocType = pqReq.Substring(0, pqReq.IndexOf(#"\t"));
The string pqReq is like this: "CSTrlsEN\t001\t\\sgprt\Projects2\t001\tCSTrl". But even though I can clearly see the t\ in the string, pqReq.IndexOf(#"\t") returns -1, so an error is thrown.
What's the correct way to do this? I don't want to split the string pqReq until later on in the code.
Use \\t instead of \t. The \t is seen as a tab-character. sDocType = pqReq.Substring(0, pqReq.IndexOf(#"\t"));
Edit:
I didn't notice the \t being literal due to the #. But is your input string a literal string? If not, place an # before the value of pqReq.
string pqReq = #"CSTrlsEN\t001\t\\sgprt\Projects2\t001\tCSTrl";
int i = pqReq.IndexOf(#"\t");
//i = 8
I can't reproduce this issue. The following code (.NET Fiddle here):
var pqReq=#"CSTrlsEN\t001\t\\sgprt\Projects2\t001\tCSTrl";
var idx=pqReq.IndexOf(#"\t");
Console.WriteLine(idx);
var sDocType = pqReq.Substring(0, idx);
Console.WriteLine(sDocType);
produces:
8
CSTrlsEN
Did you forget to prefix pqReq with #?
Here is the code:
namespace TrimTest
{
class Program
{
static void Main(string[] args)
{
string ToTrim = "PRN.NUL";
Console.WriteLine(ToTrim);
string Trimmed = ToTrim.TrimStart("PRN.".ToCharArray());
Console.WriteLine(Trimmed);
ToTrim = "PRN.AUX";
Console.WriteLine(ToTrim);
Trimmed = ToTrim.TrimStart("PRN.".ToCharArray());
Console.WriteLine(Trimmed);
ToTrim = "AUX.NUL";
Console.WriteLine(ToTrim);
Trimmed = ToTrim.TrimStart("AUX.".ToCharArray());
Console.WriteLine(Trimmed);
}
}
}
The output is like this:
PRN.NUL
UL
PRN.AUX
AUX
AUX.NUL
NUL
As you can see, the TrimStart took out the N from NUL. But it doesn't do that for other strings even if it started with PRN.
I tried with .NET Framework 3.5 and 4.0 and the results are same. Are there any explanation on what causes this behavior?
String.TrimStart works on a character level. What you're doing is you're telling it to remove any "P", "R", "N" or "." characters from the start - therefore the first N after the dot also gets removed.
If you want to remove a certain string from the start of the string, first use StartsWith to ensure it's there and then Substring to take the correct part of the string.
Try this:
string ToTrim = "PRN.NUL";
string Trimmed = ToTrim.TrimStart(".NRP".ToCharArray());
Console.WriteLine(Trimmed);
Notice anything?
#MattiVirkkunen's answer is correct. However, here is a solution, use this extension method instead of RemoveStart method to get your desired results.
public static String RemoveStart(this string s, string text)
{
return s.Substring(s.IndexOf(s) + text.Length, s.Length - text.Length);
}