Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Improve this question
I have tried to convert the string "-1,37739,38739" into an integer in order to pass the integer into a predefined method.
I'm getting System.FormatException: 'Input string was not in a correct format.'
var dc1 = Convert.ToInt32(item.Path.ToString());
he item.Path come from a query value predefined as a string, I have to convert that string into an integer, it's coming with the above mentioned string value
-1,37739,38739 is - reformatted - -13,773,938,739; int.MinValue (the most negative value a 32-bit signed integer can represent) is -2,147,483,648 - so: it won't fit. Try long instead of int, i.e. ToInt64.
You may also need to specify an explicit culture (depending on your locale), and be a little more... forgiving re group separators:
if (long.TryParse("-1,37739,38739",
NumberStyles.Integer | NumberStyles.AllowThousands,
CultureInfo.InvariantCulture, out var val))
{
Console.WriteLine(val); // works
}
This not a surprise.
1st : -1,37739,38739 is not properly formatted. This should be either
-13773938739
or
-13,773,938,739 (or -13 773 938 739 depending on your locale)
2nd: Int32 is an integer based on 32 bits which gives min and max values -2,147,483,648 and 2,147,483,647
See documentation here Int32
If you want to convert a string which is not controlled upfront, then I would suggest you "clean" it
string item = "-1,37739,38739";
Regex rgx = new Regex("[^a-zA-Z0-9 -]");
item = rgx.Replace(item, "");
and maybe convert to Int64
var dc1 = Convert.ToInt64(item);
If you want to avoid exception, you also can try to parse the string (once cleaned)
if (Int64.TryParse(item, out var dc1))
{
// doSomething
}
else
{
// handle error
}
string item = "-1,37739,38739";
var munyamatindike=Convert.ToInt32(item);
the above code snippet should fix the error.enter image description here
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 1 year ago.
Improve this question
I am trying to display the original value in C# three part display format. I got unexpected result + 29291221321. I am expecting + 29.12121321. Is this a bug or what am I doing wrong?
double value1 = 29.1221321;
string formattingString = $"+ {value1}; - {value1}; 0";
// returns "+29.1221321; -29.1221321; 0"
Console.WriteLine(value1.ToString(formattingString));
// returns "+ 29291221321"
Please refer to why i call ToString at the end. It is something known as three part format to separate outcome quickly based on +, - and 0 value
https://diptimayapatra.wordpress.com/2014/01/13/3-part-format-of-numbers-in-c/
Note:
I am not expecting to hardcode by specify x numbers of # after decimal places. Please advise if there is a better method of displaying the original decimal value in three part format
string formattingString = "+ #.############; - #.############; 0";
Please advise if there is a better method of displaying the original decimal value in three part format
# is already the best way to express what you want, since it will omit non-significant zeros at the end. A double has about 15 to 17 significant digits, so you can put 17 # at the end of your format specifier to get the original value.
double value1 = 1.23456;
string formattingString = "+ #.#################; - #.#################; 0";
Console.WriteLine(value1.ToString(formattingString));
Console.WriteLine((-value1).ToString(formattingString));
Console.WriteLine(0.ToString(formattingString));
Output (note the leading spaces, because you have spaces in your format specifier):
+ 1,23456
- 1,23456
0
Check that for a double value with more digits
double value1 = 1.2345678901234567890123; // too many digits for a double
and compare it to the output of
Console.WriteLine(value1);
You're putting the value into the format specifier instead of your specifier:
string formattingString = $"+ {value1}; - {value1}; 0";
Your snippet should instead look like this:
double value1 = 29.1221321;
string formattingString = $"+ #.############; - #.############; 0";
Console.WriteLine(value1.ToString(formattingString));
With the added understanding that you do not want to use the hard coded number of decimal places (which is understandable given the precision available with double), I'm not aware of a way using interpolation. I'd recommend a simple extension method for it:
public static string ToSignedString(this double value) {
if (value < 0)
return $"-{value}";
else if (value > 0)
return $"+{value}";
return "0";
}
I don't typically recommend extension methods, but I believe your reasoning for not wanting hard coded decimal places is perhaps the need for the code to be concise due to heavy use.
double value = 29.1221321;
Console.WriteLine(value.ToSignedString());
Not the most graceful solution, but it would work.
You try to reformat Value1 another time in the Console.WriteLine
Change it to :
Console.WriteLine(formattingString);
I'm making simple program in C# just for fun, where I'm coding simple HEX to String -translation method like this:
private String translate(String hex)
{
StringBuilder output = new StringBuilder();
int i = 0;
while (i+2 <= hex.Length)
{
String str = hex.Substring(i, i + 2);
output.Append((char)Convert.ToInt32(str, 16));
i += 2;
}
Every time when I'm running the application, I'm getting unhandled exception "Out of ranges and bounds", and getting message, that index and point of Substring method parameters have to refer to some point of hex -String. I did the if -statement before Substring -method line with conditions true only if i +2 is smaller or equal to hex.Length, but this did not work properly. My application works properly, when I'm using only one byte HEX input String meaning one ASCII -character. Can anyone help me with this that I could go forward with my project?
Use:
hex.Substring(i, 2)
The second argument in Substring is length, not end.
Ok, hey. I made a program for an in-game.. game. And I have it load data for a player from their own .txt on my computer. Whenever i try to command (.load) it tells me (at split[1] where it is converted to an int32) which is just a test to see if your bombs load, input string is not in correct format, heres the code:
StreamReader streemy = new StreamReader(#"c:\Usernames\" + player[m.GetInt(0)].username + ".txt");
string read = streemy.ReadToEnd();
if (!string.IsNullOrEmpty(read))
{
string[] split = read.Split('=');
player[m.GetInt(0)].bombs = Convert.ToInt32(split[1]);
Say(names[m.GetInt(0)].ToUpper() + ": You data has been loaded!");
streemy.Close();
}
else
{
Say(names[m.GetInt(0)].ToUpper() + ": Your data was empty :( Say '.save' to save your current data!");
}
.save Saves the data to the .txt, "names[m.GetInt(0)]" is their username, Say just tells them in the game the message. Thanks for your help! PS: player is a struct, which has ints like bombs.
I would suggest you to use Int32.TryParse instead of Convert.ToInt32.
So if the value is not valid integer then you can treat as 0 or no bomb.
int numberOfBombs = 0;
bool result = Int32.TryParse(value, out numberOfBombs);
now numberOfBombs would retain the actual value if there is valid integer field present otherwise it will be 0.
You must be getting a FormatException.
FormatException is thrown when the arguement is not in valid format.
I think that the value of split[1] is not a valid integer.
According to msdn.
FormatException : value does not consist of an optional sign followed by a sequence of digits (0 through 9).
Using the ToInt32(string) method is equivalent to passing value to the Int32.Parse(String) method. value is interpreted by using the formatting conventions of the current thread culture.
You can call the Int32.TryParse method instead. It returns a Boolean value that indicates whether the conversion succeeded or failed.
I have a string when a telephone number is inputted - there is a mask so it always looks like "(123) 456-7890" - I'd like to take the formatting out before saving it to the DB.
How can I do that?
One possibility using linq is:
string justDigits = new string(s.Where(c => char.IsDigit(c)).ToArray());
Adding the cleaner/shorter version thanks to craigmoliver
string justDigits = new string(s.Where(char.IsDigit).ToArray())
You can use a regular expression to remove all non-digit characters:
string phoneNumber = "(123) 456-7890";
phoneNumber = Regex.Replace(phoneNumber, #"[^\d]", "");
Then further on - depending on your requirements - you can either store the number as a string or as an integer. To convert the number to an integer type you will have the following options:
// throws if phoneNumber is null or cannot be parsed
long number = Int64.Parse(phoneNumber, NumberStyles.Integer, CultureInfo.InvariantCulture);
// same as Int64.Parse, but returns 0 if phoneNumber is null
number = Convert.ToInt64(phoneNumber);
// does not throw, but returns true on success
if (Int64.TryParse(phoneNumber, NumberStyles.Integer,
CultureInfo.InvariantCulture, out number))
{
// parse was successful
}
Since nobody did a for loop.
long GetPhoneNumber(string PhoneNumberText)
{
// Returns 0 on error
StringBuilder TempPhoneNumber = new StringBuilder(PhoneNumberText.Length);
for (int i=0;i<PhoneNumberText.Length;i++)
{
if (!char.IsDigit(PhoneNumberText[i]))
continue;
TempPhoneNumber.Append(PhoneNumberText[i]);
}
PhoneNumberText = TempPhoneNumber.ToString();
if (PhoneNumberText.Length == 0)
return 0;// No point trying to parse nothing
long PhoneNumber = 0;
if(!long.TryParse(PhoneNumberText,out PhoneNumber))
return 0; // Failed to parse string
return PhoneNumber;
}
used like this:
long phoneNumber = GetPhoneNumber("(123) 456-7890");
Update
As pr commented many countries do have zero's in the begining of the number, if you need to support that, then you have to return a string not a long. To change my code to do that do the following:
1) Change function return type from long to string.
2) Make the function return null instead of 0 on error
3) On successfull parse make it return PhoneNumberText
You can make it work for that number with the addition of a simple regex replacement, but I'd look out for higher initial digits. For example, (876) 543-2019 will overflow an integer variable.
string digits = Regex.Replace(formatted, #"\D", String.Empty, RegexOptions.Compiled);
Aside from all of the other correct answers, storing phone numbers as integers or otherwise stripping out formatting might be a bad idea.
Here are a couple considerations:
Users may provide international phone numbers that don't fit your expectations. See these examples So the usual groupings for standard US numbers wouldn't fit.
Users may NEED to provide an extension, eg (555) 555-5555 ext#343 The # key is actually on the dialer/phone, but can't be encoded in an integer. Users may also need to supply the * key.
Some devices allow you to insert pauses (usually with the character P), which may be necessary for extensions or menu systems, or dialing into certain phone systems (eg, overseas). These also can't be encoded as integers.
[EDIT]
It might be a good idea to store both an integer version and a string version in the database. Also, when storing strings, you could reduce all punctuation to whitespace using one of the methods noted above. A regular expression for this might be:
// (222) 222-2222 ext# 333 -> 222 222 2222 # 333
phoneString = Regex.Replace(phoneString, #"[^\d#*P]", " ");
// (222) 222-2222 ext# 333 -> 2222222222333 (information lost)
phoneNumber = Regex.Replace(phoneString, #"[^\d]", "");
// you could try to avoid losing "ext" strings as in (222) 222-2222 ext.333 thus:
phoneString = Regex.Replace(phoneString, #"ex\w+", "#");
phoneString = Regex.Replace(phoneString, #"[^\d#*P]", " ");
Try this:
string s = "(123) 456-7890";
UInt64 i = UInt64.Parse(
s.Replace("(","")
.Replace(")","")
.Replace(" ","")
.Replace("-",""));
You should be safe with this since the input is masked.
You could use a regular expression or you could loop over each character and use char.IsNumber function.
You would be better off using regular expressions. An int by definition is just a number, but you desire the formatting characters to make it a phone number, which is a string.
There are numerous posts about phone number validation, see A comprehensive regex for phone number validation for starters.
As many answers already mention, you need to strip out the non-digit characters first before trying to parse the number. You can do this using a regular expression.
Regex.Replace("(123) 456-7890", #"\D", String.Empty) // "1234567890"
However, note that the largest positive value int can hold is 2,147,483,647 so any number with an area code greater than 214 would cause an overflow. You're better off using long in this situation.
Leading zeros won't be a problem for North American numbers, as area codes cannot start with a zero or a one.
Alternative using Linq:
string phoneNumber = "(403) 259-7898";
var phoneStr = new string(phoneNumber.Where(i=> i >= 48 && i <= 57).ToArray());
This is basically a special case of C#: Removing common invalid characters from a string: improve this algorithm. Where your formatng incl. White space are treated as "bad characters"
'you can use module / inside sub main form VB.net
Public Function ClearFormat(ByVal Strinput As String) As String
Dim hasil As String
Dim Hrf As Char
For i = 0 To Strinput.Length - 1
Hrf = Strinput.Substring(i, 1)
If IsNumeric(Hrf) Then
hasil &= Hrf
End If
Next
Return Strinput
End Function
'you can call this function like this
' Phone= ClearFormat(Phone)
public static string DigitsOnly(this string phoneNumber)
{
return new string(
new[]
{
// phoneNumber[0], (
phoneNumber[1], // 6
phoneNumber[2], // 1
phoneNumber[3], // 7
// phoneNumber[4], )
// phoneNumber[5],
phoneNumber[6], // 8
phoneNumber[7], // 6
phoneNumber[8], // 7
// phoneNumber[9], -
phoneNumber[10], // 5
phoneNumber[11], // 3
phoneNumber[12], // 0
phoneNumber[13] // 9
});
}