I have a string being passed to me which can be between 1 and 6 characters long. Depending on the length of the string I need to add the appropriate prefix to the start of the string and return the appeneded string. So if I have something like the following passed to me
1
12
123
1234
12345
123456
I want the return string to look like
X000001
X000012
X000123
X001234
X012345
X123456
I have come up with the following method
public static string AddToStartOfString(string s)
{
string value = string.Empty;
switch (s.Length)
{
case 1:
value = "X00000" + s;
break;
case 2:
value = "X0000" + s;
break;
case 3:
value = "X000" + s;
break;
case 4:
value = "X00" + s;
break;
case 5:
value = "X0" + s;
break;
case 6:
value = "X" + s;
break;
}
return value;
}
This works. But I need this to work in case in future more lengths are added. Is there a way where I can add the prefix even if the length of string is greater than 6 in the future
You can do this:
public static string AddToStartOfString(string s, int digitCount = 6)
{
return "X" + s.PadLeft(digitCount, '0');
}
Beware that an input string longer than the max number of digits, once transformed, will not be truncated and will be longer than for values in the correct range.
had a similar problem recently, in your case i would do:
public static string Fill(string str, string prefix, int length)
{
for(int i=str.Length; i<length; i++)
str = "0" + str;
return prefix + str;
}
Related
I want to make "." and "," to both work as decimal numbers. My problem is that by default on my computer it is "."(23.33 works) and it does error when i try putting "," (23,33). How can I make it work.
private static Double SolveExpression(String expression)
{
char uiSep = CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator[0];
expression = expression.Replace('.', uiSep);
expression = expression.Replace(',', uiSep);
if (expression.StartsWith("("))
{
int opening_brackets = 1, closing_brackets = 0, current_symbol = 1;
while (opening_brackets != closing_brackets)
{
if (expression[current_symbol] == '(')
opening_brackets++;
else if (expression[current_symbol] == ')')
closing_brackets++;
current_symbol++;
}
String expr = expression.Substring(1, current_symbol - 2);
expression = expression.Remove(0, current_symbol);
Match operation = Regex.Match(expression, #"^[\+\-\*\/]");
if (operation.Success)
{
expression = expression.Remove(0, operation.Value.Length);
switch (operation.Value)
{
case "+":
{
return SolveExpression(expr) + SolveExpression(expression);
}
case "-":
{
return SolveExpression(expr) - SolveExpression(expression);
}
case "*":
{
return SolveExpression(expr) * SolveExpression(expression);
}
case "/":
{
return SolveExpression(expr) / SolveExpression(expression);
}
}
}
else
return SolveExpression(expr);
}
Match constant = Regex.Match(expression, #"(^-*\d+)((\.|\,)(\d+))?");
if (constant.Success)
{
expression = expression.Remove(0, constant.Value.Length);
Match operation = Regex.Match(expression, #"^[\+\-\*\/]");
if (operation.Success)
{
expression = expression.Remove(0, operation.Value.Length);
switch (operation.Value)
{
case "+":
{
return Double.Parse(constant.Value) + SolveExpression(expression);
}
case "-":
{
return Double.Parse(constant.Value) - SolveExpression(expression);
}
case "*":
{
return Double.Parse(constant.Value) * SolveExpression(expression);
}
case "/":
{
return Double.Parse(constant.Value) / SolveExpression(expression);
}
}
}
else
return Double.Parse(constant.Value);
}
else
//throw new Exception("Invalid Expression");
MessageBox.Show("You have entered invalid expression! Revise and try again", "Something went wrong", MessageBoxButtons.OK,MessageBoxIcon.Error);
return 0;
}
If you want to support either character as a decimal point but not accept thousands separators then the easiest way is to just replace all , with . and use CultureInfo.InvariantCulture:
stringValue = stringValue.Replace(',','.');
double.TryParse(stringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out double doubleValue)
However, if a user supplies a value with a thousands separator (with or without a decimal), then this method will give wrong results.
Didn't get what you mean exactly. But here is something that can help with the Numeric format of a string:
double [] value = {123.456,567.1};
Console.WriteLine("Your account balance is {0:C2}.", value[0],value[1]);
Console.WriteLine("Your account balance is {1:C3}.", value[0],value[1]);
// Displays "Your account balance is $123.46."
// "Your account balance is $567.100."
where: 0 and 1 are the elements of the value array, value[0] and value1.
C2 and C3 is showing in the currency format with two and three digits after decimal
for details and more check this out
Using the regex in the line of:
\-?[0-9]+[\.\,][0-9]+
This will allow numbers in the form of:
12.34
12,34
-12.34
-12,34
Then by using the string.Replace
it is possible to do this:
input = input.Replace(",", ".")
var numberFormat = System.Globalization.CultureInfo.InvariantCulture.NumberFormat;
double value = Convert.ToDouble(TextBox.Text, numberFormat);
The number can be parsed.
Try this:
var str = "1.25";
var str2 = "1,25";
double Parse(string txt){
return double.Parse(txt.Replace(",",".")
.Replace(".", CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator));
}
Parse(str); // not crashing
Parse(str2); // not crashing
I am creating a C# Console app which is Replacing a Hyphen for Zeros to complete the maximum length of my String from an identification card "123456-72"and I am facing a hard time when have to sort in my array.
I would like sort the first digit or character from this "123456-72" as well in some cases I need to sort from the first two digit "391234-56".
This example is working fine, but only for first character. I need to
Example:
class IdentificationNumber {
private string IDNumber;
private int Customertype;
private string check;
private string pad;
private string longFormat;
SortedList GroupID = new SortedList();
public IdentificationNumber(string IDNumber) {
this.IDNumber= IDNumber;
}
public string getLongFormat() {
var ReplaceHyp = IDNumber.Replace("-", "");
int Customertype= Int32.Parse(IDNumber.Substring(0,2));
//Array
//GroupID .Add(1,"Blue");
//GroupID .Add(2,"Blue");
GroupID .Add(38,"White");
GroupID .Add(39,"Blue");
pad="";
check = GroupID.GetByIndex(GroupID.IndexOfKey(Customertype)).ToString();
Console.WriteLine(Customertype);
Console.WriteLine(check);
switch (check) {
case("White"):
longFormat= ReplaceHyp.Substring(0,6)+pad.PadLeft((14 -ReplaceHyp.Length),'0')+ReplaceHyp.Substring(6,(ReplaceHyp.Length-6));
break;
case("Blue"):
longFormat= ReplaceHyp.Substring(0,7)+pad.PadLeft((14 -ReplaceHyp.Length),'0')+ReplaceHyp.Substring(7,(ReplaceHyp.Length-7));
break;
}
return longFormat;
}
}
Any solution or suggestion?
Here is a skeleton of the comparator method you might need:
public static int CompareStrings(string s1, string s2)
{
int Customertype1 = Int32.Parse(s1.Substring(0,2));
int Customertype2 = Int32.Parse(s2.Substring(0,2));
string check1 = GroupID.GetByIndex(GroupID.IndexOfKey(Customertype1)).ToString();
string check2 = GroupID.GetByIndex(GroupID.IndexOfKey(Customertype2)).ToString();
if (Customertype1 > Customertype2)
return 1;
if (Customertype1 < Customertype2)
return -1;
else
{
var ReplaceHyp1 = s1.Replace("-", "");
switch (check1) {
case("White"):
longFormat1 = ReplaceHyp1.Substring(0,6)+pad.PadLeft((14 -ReplaceHyp1.Length),'0')+ReplaceHyp1.Substring(6,(ReplaceHyp1.Length-6));
break;
case("Blue"):
longFormat1 = ReplaceHyp1.Substring(0,7)+pad.PadLeft((14 -ReplaceHyp1.Length),'0')+ReplaceHyp1.Substring(7,(ReplaceHyp1.Length-7));
break;
}
var ReplaceHyp2 = s2.Replace("-", "");
switch (check2) {
case("White"):
longFormat2 = ReplaceHyp2.Substring(0,6)+pad.PadLeft((14 -ReplaceHyp2.Length),'0')+ReplaceHyp2.Substring(6,(ReplaceHyp2.Length-6));
break;
case("Blue"):
longFormat2 = ReplaceHyp2.Substring(0,7)+pad.PadLeft((14 -ReplaceHyp2.Length),'0')+ReplaceHyp2.Substring(7,(ReplaceHyp2.Length-7));
break;
}
return stringCompare(longFormat1, longFormat2);
}
}
This code badly needs to be refactored! Depending on your exact needs, I think that the checks of Customertype1/2 can be removed.
The last but 3rd line of code is not recognizing variables that I have declared and filled with strings.
static void Main(string[] args)
{
string inputNumber = "1979";
string input1 = inputNumber.Substring(0, 1);
string input2 = inputNumber.Substring(1, 1);
string input3 = inputNumber.Substring(2, 1);
string input4 = inputNumber.Substring(3, 1);
int intInput1;
int intInput2;
int intInput3;
int intInput4;
intInput1 = Convert.ToInt32(input1);
intInput2 = Convert.ToInt32(input2);
intInput3 = Convert.ToInt32(input3);
intInput4 = Convert.ToInt32(input4);
string stringOutput1;
string stringOutput2;
string stringOutput3;
string stringOutput4;
// 1000 Input.
switch (intInput1)
{
case 1:
stringOutput1 = "M";
break;
default:
break;
}
//100 Input
switch (intInput2)
{
case 9:
stringOutput2 = "CM";
break;
default:
break;
}
//10 Input
switch (intInput3)
{
case 7:
stringOutput3 = "LXX";
break;
default:
break;
}
//1 Input
switch (intInput4)
{
case 9:
stringOutput4 = "IX";
break;
default:
break;
}
//Use of unassigned local variable error is showing for 'stringOutput1', 'stringOutput2', 'stringOutput3' and 'stringOutput4'
Console.WriteLine("{0} is {1}{2}{3}{4} in Roman Numerals",inputNumber, stringOutput1, stringOutput2, stringOutput3, stringOutput4);
Console.CursorVisible = false;
Console.ReadKey();
}
P.S. I know that the variables are being filled by commenting out
Console.WriteLine("{0} is {1}{2}{3}{4} in Roman Numerals",inputNumber, stringOutput1, stringOutput2, stringOutput3, stringOutput4);
and using break point and stepping over the code.
This is because your variables might not have been assigned anything yet. Variables must be guaranteed to have been assigned something before they can be used. As a simple fix, you can use declarations like this:
string stringOutput1 = "";
Try assigning nulls to the declarations
string stringOutput1 = null;
string stringOutput2 = null;
string stringOutput3 = null;
string stringOutput4 = null;
You have to initialize your variables, do it like this.
string stringOutput1 , stringOutput1, stringOutput3, stringOutput4 = string.Empty;
and you can also assign default values per variable.
string stringOutput1 = "foo1", stringOutput1 = "foo2"
, stringOutput3= "foo3", stringOutput4 = "foo4";
How would I make a switch statement populate a list, or comma delimited string?
For example
switch(test)
{
case 0:
"test"
break;
case 1:
"test2"
break;
case 2:
"test3"
break;
}
So my program will go into this statement multiple times. So lets say it goes in there twice and has case 2 and case 1. I woulld like a string value containing the following:
string value = "test3, test2"
Looks like a List<string> would be ideal to hold your values, you can create a comma separated string from that using string.Join():
List<string> myList = new List<string>();
//add items
myList.Add("test2");
//create string from current entries in the list
string myString = string.Join("," myList);
By multiple times, you mean a loop? You can just have a string and concatenate the string using + operator, or you can just have a list and add to it everytime the case condition is satisfied.
But if you mean by conditional flow so that you want case 0, 1 and 2 to all be evaluated, then you can simply omit the break and do the same concatenation like I mentioned above.
private string strValue = string.Empty;
private string StrValue
{
get
{
return strValue ;
}
set
{
StrValue= string.Concat(strValue , ",", value);
}
}
switch(test)
{
case 0:
StrValue = "test"
break;
case1:
StrValue = "test2"
break;
case 2:
StrValue = "test3"
breakl
}
Where ever you used StrValue remove "," if "," comes in the last.
There's a couple ways you can do it, a very simple one is:
string csv = "";
while (yourCriteria) {
string value;
// insert code to get your test value
switch(test)
{
case 0:
value = "test";
break;
case1:
value = "test2";
break;
case 2:
value = "test3";
break;
}
csv += value + ", ";
}
csv = csv.Length > 0 ? csv.Substring(0, csv.Length-2) : "";
Use a loop and a StringBuilder. If you're doing repeated concatenation, StringBuilders are significantly more efficient than naive string concatenation with +.
StringBuilder sb = new StringBuilder();
for(...)
{
switch(test)
{
case 0:
sb.Append("test");
break;
case1:
sb.Append("test2");
break;
case 2:
sb.Append("test3");
break;
}
}
I am trying to create a an function that formats US phone numbers -- hopefully without looping through each digit.
When 10 digits are passed in all is fine. How ever when more than 10 digits are passed in
I want the String.Format method to append the extension digits on the right. For example:
When 14 digits passed in the result should be:(444)555-2222 x8888
When 12 digits passed in the result should be:(444)555-2222 x88
etc.
However what I get with my current attempt is:
Passing in 12 digits returns this string '() -949 x555444433'
here is what I have so far.
public static string _FormatPhone(object phonevalue)
{
Int64 phoneDigits;
if (Int64.TryParse(phonevalue.ToString(), out phoneDigits))
{
string cleanPhoneDigits = phoneDigits.ToString();
int digitCount = cleanPhoneDigits.Length;
if (digitCount == 10)
return String.Format("{0:(###) ###-####}", phoneDigits);
else if (digitCount > 10)
return String.Format("{0:(###) ###-#### x#########}", phoneDigits);
else
return cleanPhoneDigits;
}
return "Format Err#";
}
Thanks in advance.
I think you'll have to break your phoneDigits string into the first 10 digits and the remainder.
//[snip]
else if (phoneDigits.ToString().Length > 10)
{
return String.Format("{0:(###) ###-#### x}{1}", phoneDigits.Substring(0,10), phoneDigits.Substring(10) );
}
//[snip]
I'd suggest treating it as a string of digits, not a number. You would then use Substring explicitly to break out the parts.
Trying to squeeze it into 1 line, I came up with this.
var phoneNumber = "(999) 555-4455 ext123";
phoneNumber = Regex.Replace(phoneNumber, "(.*?)([+]\\d{1,3})?(.*?)(\\d{3})(.*?)(\\d{3})(.*?)(\\d{4})([ ]+)?(x|ext)?(.*?)(\\d{2,5})?(.*?)$", "$2 $4 $6 $8 $10$12").Trim().Replace("ext","x");
If it starts with +# it will leave that alone. It will then look for blocks of numbers. 3,3,4 then it looks for ext or x for extension and another 2-5 numbers. At that point you can format it anyway you like, I chose spaces.
1234567890 -> '123 456 7890'
(123)456.7890 -> '123 456 7890'
+1 (999)555-4455 ext123 -> '+1 999 555 4455 x123'
The problem lies in your else if condition where you have a set number of # placeholders to handle the phone number extension. Instead, we can define the format dynamically to account for different lengths.
Why are you passing in an object? You're using ToString() all over the place. Why not pass in a string from the start? If the item you're passing in isn't a string then call ToString before passing it in, or save the ToString() result in a variable in the method as shown below.
Here's an updated version of your method:
public static string _FormatPhone(object phonevalue)
{
string returnPhone = "Format Err#";
Int64 phoneDigits;
string phoneNumber = phonevalue.ToString();
if (Int64.TryParse(phoneNumber, out phoneDigits))
{
if (phoneNumber.Length == 10)
{
return phoneDigits.ToString("(###) ###-####");
}
else if (phoneNumber.Length > 10)
{
// determine the length of placeholders needed for the format
string format = "(###) ###-#### x"
+ new string('#', phoneNumber.Length - 10);
return phoneDigits.ToString(format);
}
else
{
return phoneNumber;
}
}
return returnPhone;
}
To test it:
string[] inputs = { "456", "4445552222", "444555222288", "44455522226789" };
foreach (string input in inputs)
{
Console.WriteLine("Format Result: " + _FormatPhone(input));
}
There's no need for a regex in this case. If you really wanted to use one though, your replacement method needs to determine the length in order to append the extension when needed as shown below:
string[] inputs = { "456", "4445552222", "444555222288", "44455522226789" };
string pattern = #"(\d{3})(\d{3})(\d{4})(\d*)";
foreach (string input in inputs)
{
string result = Regex.Replace(input, pattern, m =>
{
if (m.Value.Length >= 10)
{
return String.Format("({0}) {1}-{2}",
m.Groups[1].Value, m.Groups[2].Value, m.Groups[3].Value)
+ (m.Value.Length > 10 ? " x" + m.Groups[4].Value : "");
}
return m.Value;
});
Console.WriteLine("Regex result: " + result);
}
using a regex:
Regex usPhoneRegex = new Regex(#"(\d{3})(\d{3})(\d{4})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
string USPhoneFormatString = "$1-$2-$3 x$4";
return usPhoneRegex.Replace("312588230012999", USPhoneFormatString));
Anything after the main phone number will be returned as an extension
Since you were using an int64 in your code, my regex assumes there are no spaces or punctuation in the phone number.
-- Edit --
Ahmad pointed out that I was not handling the case of a number without an extension. So here is a revised version that uses a MatchEvaluator to do the job. Is it better than the other answers? I don't know - but it is a different approach so I thought I would toss it out there.
Regex usPhoneRegex = new Regex(#"(\d{3})(\d{3})(\d{4})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
return usPhoneRegex.Replace("3125882300", new MatchEvaluator(MyClass.formatPhone))
public static string formatPhone(Match m) {
int groupIndex = 0;
string results = string.Empty;
foreach (Group g in m.Groups) {
groupIndex +=1;
switch (groupIndex) {
case 2 :
results = g.Value;
break;
case 3 :
case 4 :
results += "-" + g.Value;
break;
case 5 :
if (g.Value.Length != 0) {
results += " x " + g.Value;
}
break;
}
}
return results;
}
This should probably use a StringBuilder.
Try using regular expressions:
class Program
{
static void Main(string[] args)
{
var g = FormatUSPhone("444555222234");
}
public static string FormatUSPhone(string num)
{
string results = string.Empty;
if(num.Length == 10)
{
num = num.Replace("(", "").Replace(")", "").Replace("-", "");
const string formatPattern = #"(\d{3})(\d{3})(\d{4})";
results = Regex.Replace(num, formatPattern, "($1) $2-$3");
}else if (num.Length == 12)
{
num = num.Replace("(", "").Replace(")", "").Replace("-", "");
const string formatPattern = #"(\d{3})(\d{3})(\d{4})(\d{2})";
results = Regex.Replace(num, formatPattern, "($1) $2-$3 x$4");
}
return results;
}
I edited the above from an example I found here. Play about with the above code, see if it helps you.