I have a string format which includes two integer variables, each of which needs to be formatted to a variable length:
int x = 1234;
int y = 42;
// Simplified, real values come from method outputs, so must use the variables:
int xFormatDigitCount = 7;
int yFormatDigitCount = 3;
var xStringFormat = new string('0', xFormatDigitCount); // "0000000"
var yStringFormat = new string('0' ,yFormatDigitCount); // "000"
For now I only managed to get the desired format using the integer variables' .ToString() methods:
var xString = x.ToString(xStringFormat);
var yString = y.ToString(yStringFormat);
return $"{xString}-{yString}";
But this seems like an overhead since string interpolation supports the format {var:format}. Is there a way to get my string with only string interpolation, without using x and y's ToString()?
I'm not sure I understand the question, but format specifiers for string.Format and, thus, string interpolation are textual - they don't accept variables.
You either use static format specifiers:
$"{x:0000000}-{y:000}"
Or resort to the good old string.Format:
string.Format(
$"{{0:{new string('0', xFormatDigitCount)}}}-{{1:{new string('0', yFormatDigitCount)}}}",
x,
y);
Edit:
Based on weston's answer:
$"{x.ToString($"D{xFormatDigitCount}")}-{y.ToString($"D{yFormatDigitCount}")}"
Is there a way to get my string with only string interpolation, without using x and y's ToSTring()
I don't believe so, but it can be so much cleaner thanks to ToString("Dx"):
All in one (nested interpolations):
public string Format(int x, int y, int xDigitCount, int yDigitCount)
{
return $"{x.ToString($"D{xDigitCount}")}-{y.ToString($"D{yDigitCount}")}";
}
Stack Overflow syntax highlighting can't keep up, so it looks odd, but this is how it looks in VS:
You can just call the ToString method within the interpolated string.
$"{x.ToString(xStringFormat)}-{y.ToString(yStringFormat)}"
Related
I know that C# has some options to format decimal numbers with some extended logic in the ToString() method, as e.g.
double d1 = 1.3333;
double d2 = 1.6666;
string d1Str = d1.ToString("#0.00"); // 1.33
string d2Str = d2.ToString("#0.00"); // 1.67
That's great, my number is rounded to the second decimal. But what if I wanted to round to a step of 0.05 instead of 0.01? Is there a way to use the ToString() method in a similar way to round the value not to a given step-size (e.g. 0.05)?
Note: I know I could do something like this:
(Math.Round(1.33333*20)/20).ToString();
but the question is about getting this result using ToString() only.
Is it possible for you to create an extension overload for ToString() for these components?
If so you could write something like:
public static class DoubleStaticExtension
{
public static string ToString(this double value, string format, int decimalToRoundHalfwayAt)
{
int modifier = 2 * (int)Math.Pow(10, decimalToRoundHalfwayAt -1 );
return (Math.Round(value * modifier, MidpointRounding.AwayFromZero) / modifier).ToString(format);
}
}
Calling that with
double d = 9.333333;
string result = d.ToString("#0.00", 2);
Would give a result of 9.35
And
double d = 9.333333;
string result = d.ToString("#0.00", 1);
Would give a result of 9.50
I need to save a string with the hexadecimal code of an int.
For example the hexadecimal value for the int 15 is xoooF.
My problem is that I have to save this code in a string like this:
int myint = myStringLength; //this value might change
string myIntExhCode = myint.convertThisIntoMyCode();
//and the string has to be exactly "/xoooF"
So in this question I have two problmes:
The first is how to automatically convert an int into the hexadecimal code like 15 = xoooF
The second is how to create a string containing \xoooF because any try of concatenating strings like this resulted into a \\xoooF and this is not correct since in output I need the string to be converted into the ascii code.
How can I achieve those two tasks?
Any help will be appreciated
Your question is quite vague. If you want hexadecimal format, but with 0 (digit zero) changed into o (small latin letter o) you can implement, say, an extension method (in order to keep your proposed code intact):
public static partial class IntExtensions {
public static string convertThisIntoMyCode(this int value) {
return "\\x" + value.ToString("X4").Replace('0', 'o'); // or "/x" + ...
}
}
...
int myint = myStringLength; //this value might change
string myIntExhCode = myint.convertThisIntoMyCode();
// Test output
Console.Write(myIntExhCode);
How about
int i = 15;
string result = "\\x" + i.ToString("X").PadLeft(4, 'o');
I didn't get the problem - I was trying to do a simple action:
for(i = x.Length-1, j = 0 ; i >= 0 ; i--, j++)
{
backx[j] = x[i];
}
Both are declared:
String x;
String backx;
What is the problem ? It says the error in the title...
If there is a problem - is there another way to do that?
The result (As the name 'backx' hints) is that backx will contain the string X backwards.
P.S. x is not empty - it contains a substring from another string.
Strings are immutable: you can retrieve the character at a certain position, but you cannot change the character to a new one directly.
Instead you'll have to build a new string with the change. There are several ways to do this, but StringBuilder does the job in a similar fashion to what you already have:
StringBuilder sb = new StringBuilder(backx);
sb[j] = x[i];
backx = sb.ToString();
EDIT: If you take a look at the string public facing API, you'll see this indexer:
public char this[int index] { get; }
This shows that you can "get" a value, but because no "set" is available, you cannot assign values to that indexer.
EDITx2: If you're looking for a way to reverse a string, there are a few different ways, but here's one example with an explanation as to how it works: http://www.dotnetperls.com/reverse-string
String is immutable in .NET - this is why you get the error.
You can get a reverse string with LINQ:
string x = "abcd";
string backx = new string(x.Reverse().ToArray());
Console.WriteLine(backx); // output: "dcba"
String are immuatable. You have convert to Char Array and then you would be able to modify.
Or you can use StringBuilder.
for example
char[] wordArray = word.ToCharArray();
In C# strings are immutable. You cannot "set" Xth character to whatever you want. If yo uwant to construct a new string, or be able to "edit" a string, use i.e. StringBuilder class.
Strings are immutable in C#. You can read more about it here: http://msdn.microsoft.com/en-us/library/362314fe.aspx
Both the variables you have are string while you are treating them as if they were arrays (well, they are). Of course it is a valid statement to access characters from a string through this mechanism, you cannot really assign it that way.
Since you are trying to reverse a string, do take a look at this post. It has lot of information.
public static string ReverseName( string theName)
{
string revName = string.Empty;
foreach (char a in theName)
{
revName = a + revName;
}
return revName;
}
This is simple and does not involve arrays directly.
The code below simply swaps the index of each char in the string which enables you to only have to iterate half way through the original string which is pretty efficient if you're dealing with a lot of characters. The result is the original string reversed. I tested this with a string consisting of 100 characters and it executed in 0.0000021 seconds.
private string ReverseString(string testString)
{
int j = testString.Length - 1;
char[] charArray = new char[testString.Length];
for (int i = 0; i <= j; i++)
{
if (i != j)
{
charArray[i] = testString[j];
charArray[j] = testString[i];
}
j--;
}
return new string(charArray);
}
In case you need to replace e.g. index 2 in string use this (it is ugly, but working and is easily maintainbable)
V1 - you know what you want to put their. Here you saying in pseudocode string[2] = 'R';
row3String.Replace(row3String[2], 'R');
V2 - you need to put their char R or char Y. Here string[2] = 'R' if was 'Y' or if was not stay 'Y' (this one line if needs some form of else)
row3String.Replace(row3String[2], row3String[2].Equals('Y') ? 'R' : 'Y');
My question might looks like silly, but i struck with it.
I have a string value "155.300" and i want to convert it to integer.
I tryed but throwing System.FormatException....pls someone help me out.
Since your source data is string you need to Convert it to Double first then just cast it to int or use Convert.ToInt32, but remember Convert.ToInt32 rounds it to nearest integer number, whereas casting takes the int part of the number (truncate)
double d = Convert.ToDouble("155.00");
int a = (int) d;
int b = Convert.ToInt32(d);
Or in a single Line
int b =(int) Convert.ToDouble("155.000");
EDIT
Since you want to use decimal point as thousand separator, I believe in German culture you can try the following.
int b = ((int)Convert.ToDouble("154.500", new CultureInfo("de-DE")));
That will give you 154500
EDIT 2
Or much better is to use int.Parse with NumberStyles.AllowThousands:
int b = int.Parse("154.500", NumberStyles.AllowThousands, new CultureInfo("de-DE"));
First parse it as a decimal or double (probably best to use decimal as you've got decimal data) then either cast or use something like Math.Round, depending on your requirements.
Basically, you need to always consider what data you've got: "155.300" isn't a string representation of an integer, so don't try to parse it as an integer. Parse it as what it is, then convert that to an integer.
Alternatively, you could hack at the string representation first, but personally I find that to be a more brittle approach in many cases.
EDIT: Note that if this is really already an integer, but with a thousands separator, you don't need to use double at all - you can use int.Parse, specifying an appropriate culture and number style:
int parsed = int.Parse(text, NumberStyles.Integer | NumberStyles.AllowThousands,
culture);
Here is a working conversion sample. Take a special look with the edge conditions, the output may be different if using several rounding/casting techniques
class Program
{
public static int MyToInt(string str)
{
double result;
bool success = Double.TryParse(str, out result);
if (!success)
{
throw new ArgumentException(
"Cannot parse a string into a double");
}
return Convert.ToInt32(result); // 156
//return (int)result; // 155 <<
//return (int)Math.Round(result); // 156
}
static void Main(string[] args)
{
string s = "155.500";
int value = MyToInt(s);
}
}
You can try this:
string str = "123.123";
str = str.Remove(str.IndexOf('.'), 1);
int result;
int.TryParse(str, out result);
Edit: Based on your comment, modified to multiply by thousand.
Or you can just try:
string str = "123.123";
double result;
double.TryParse(str, out result);
int final = (int)(result * 1000);
What is the best way to take a string which can be empty or contain "1.2" for example, and convert it to an integer? int.TryParse fails, of course, and I don't want to use float.TryParse and then convert to int.
Solution 1: Convert.ToDouble (culture-dependent)
You may using Convert.ToDouble. But, beware! The below solution will work only when the number separator in the current culture's setting is a period character.
var a = (int)Convert.ToDouble("1.2");
Solution 2: Convert.ToDouble (culture-independent)
It's preferable to use IFormatProvider and convert the number in an independent way from the current culture settings:
var a = (int)Convert.ToDouble("1.2", CultureInfo.InvariantCulture.NumberFormat);
Solution 3: Parse & Split
Another way to accomplish this task is to use Split on parsed string:
var a = int.Parse("1.2".Split('.')[0]);
Or:
var a = int.Parse("1.2".Split('.').First());
Notes
If you want to handle empty and null strings, write a method and add string.IsNullOrEmpty condition.
To get decimal separator for the current culture setting, you can use NumberFormatInfo.NumberDecimalSeparator property.
You should also keep eye on rounding to avoid traps.
Select casting, Parse, TryParse or Convert class wisely. Read more at:
How to: Convert a string to an int (C# Programming Guide)
How to: Determine Whether a String Represents a Numeric Value (C# Programming Guide)
I don't know what's wrong with parsing to a float and converting to an int. I doubt that any other way would be more efficient but here's an attempt:
//allows empty strings and floating point values
int ParseInt(string s, bool alwaysRoundDown = false)
{
//converts null/empty strings to zero
if (string.IsNullOrEmpty(s)) return 0;
if (!s.Contains(".")) return int.Parse(s);
string parts = s.Split(".");
int i = int.Parse(parts[0]);
if (alwaysRoundDown || parts.Length==1) return i;
int digitAfterPoint = int.Parse(parts[1][0]);
return (digitAfterPoint < 5) ? i : i+1;
}
In order to globalize the code you would need to replace "." with System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.
int a = (int)Math.Round(float.Parse("0.9"));
You need to round it first unless you want 0.9f being converted to 0 instead of 1.
Maybe you can try to delete everything after floating point using string functions and then convert to int. But seriously I don't think it's better than converting to float and then to int.
I think another way of doing it would be splitting the string into pieces taking the decimal (.) as the delimiter and then parsing for the integer. Of course, I am yet to ask you if the string might contain values like "37.56 miles in 32.65 seconds" type values.
Considering there will be only one value (string or number) in the string, I can think of something in the following line:
public int64 GetInt64(string input)
{
if (string.IsNullOrEmpty(input)) return 0;
// Split string on decimal (.)
// ... This will separate all the digits.
//
string[] words = input.Split('.');
return int.Parse(words[0]);
}
You can use the Visual Basic runtime Library to accomplish this from c#.
You need to add a reference to the assembly Microsoft.VisualBasic.dll to your solution.
Then the following code will do your conversion:
using VB = Microsoft.VisualBasic.CompilerServices;
class Program
{
static void Main(string[] args)
{
int i = VB.Conversions.ToInteger("1.2");
}
}
I had this same problem and ended up using a hybrid of Mark's and Dariusz':
if (num == "")
{
num = "0.00";
}
var num1 = (float)Convert.ToDouble(num);