I want to convert a string which contains 5 zeros ("00000") into a Int so it can be incremented.
Whenever I convert the string to an integer using Convert.ToInt32(), the value becomes 0.
How can I ensure that the integer stays at a fixed length once converted?
I want to be able to increment the value from "00000" to "00001" and so on so that the value appears with that many digits in a database instead of 0 or 1.
If you are going to down vote question, the least you could do is leave feedback on why you did it...
An integer is an integer. Nothing more.
So the int you have has value zero, there is no way to add any "length" metadata or similar.
I guess what you actually want is, that - at some point - there will be a string again. You want that string to represent your number, but with 5 characters and leading zeroes.
You can achieve that using:
string s = i.ToString("00000")
EDIT
You say you want the numbers to appear like that in your DB.
Ask yourself:
Does it really need to be like that in the DB or is it sufficient to format the numbers as soon as you read them from the database?
Depending on that, format them (as shown above), either when writing to or reading from the DB. Of course, the former case will require more storage space and you cannot really use SQL or similar to perform arithmetic operations!
An integer doesn't have a length, it's purely a numerical value. If you want to keep the length, you have to store the information about the length somewhere else.
You can wrap the value in an object that keeps the length in a property. Example:
public class FormattedInt {
private int _value, _length;
public FormattedInt(string source) {
_length = source.Length;
_value = Int32.Parse(source);
}
public void Increase() {
_value++;
}
public override string ToString() {
return _value.ToString(new String('0', _length));
}
}
Usage:
FormattedInt i = new FormattedInt("0004");
i.Increase();
string s = i.ToString(); // 0005
As olydis says above, an int is just a number. It doesn't specify the display format. I don't recommend storing it padded out with zeroes in a database either. It's an int, store it as an int.
For display purposes, in the app, a report, whatever, then pad out the zeroes.
string s = i.ToString("00000");
Related
I have a table in the (oracle) database that has a column of NUMBER(12). I can't use int in C# because that is small, so I used long. But long is too big for this table column. Is there any way to limit the size of a long before I send the data to the database? Otherwise I will get an error ORA-21525, since I exceed the size of the table column. The data send to the database is actually a List<long>.
The most obvious solution would be to use a custom number type that restricts the range of values for the number. Something like
public readonly struct Number12{
public long Value {get;}
public Number12(long num){
if(num > 999999999999 || num < -999999999999 ){
throw new ArgumentException("number out of rage " +num);
}
Value = num;
}
// Add operators, conversions etc
}
An advantage of this would be that it is obvious that this number has some special rules. But it will be more cumbersome to use, and may cause issues if the database is changed in the future.
I am trying to read values from excel sheet cells, where I find values like 123,10000. So there are always 5 decimal places. Now, I read in this value from a cell like this:
reportedAmount = _converter.ToDecimalOrZero(row[25].ToString());
The ToDecimalOrZero method looks like this:
internal decimal ToDecimalOrZero(string v)
{
String formattedDecimalInput = String.Format("{0:0.00000}", v);
try
{
return Convert.ToDecimal(formattedDecimalInput);
}
catch
{
return Convert.ToDecimal(String.Format("{0:0.00000}", 0));
}
}
Now, the issue is that the returned values will always have no trailing zeroes, regardless of how the input is. What I notice when doing some simple debugging is that the method that reads out the value from a cell is the one that removes the zeroes. However, what is confusing to me is that String.Format("{0:0.00000}", v) does not return the value with 5 decimal places, but returns the same format that the value we gave to it had (the one without trailing zeroes). Any ideas? Thank you.
Whenever I open my form (the one which stuff is being sent to) it crashes because a of a certain part. The part that is breaking it is Convert.ToInt32(txt_cost). Im looking to know how this should be sent to my other form without crashing the program
private void btn_HomepageSearch_Click(object sender, EventArgs e)
{
if (isValidData())
{
string destination = cbo_Destination.Text;
DateTime checkIn = date_FlightDate.Value;
frm_BookingPg frm_HomePge = new frm_BookingPg(cbo_Destination.Text, cbo_AmountOfPeople.Text, Convert.ToInt32(txt_cost));
frm_HomePge.Show();
this.Hide();
}
}
Assuming you have an integer in your text box, i believe that should be
Convert.ToInt32(txt_cost.Text)
if it still crashes then the value of txt_cost can't be a valid int. try the below
var intValue = 0;
if (int.TryParse(txt_cost.Text, out intValue))
{
//do something with intValue
}
EDITED
( Code part from the comment of #Minimarshman ) :
case "ten":
price1 = 10;
break;
decimal total = price * price1;
txt_cost.Text = total.ToString("c");
So as you can see you're converting decimal to string and then assign that into a TextBox's Text property.
ALWAYS leave some margin for errors especially when you're doing software development. Meaning that you should NEVER TRUST that user will use your software as it was intended. Your usage of Convert.ToInt32(txt_cost) shows that you trust your/user data too much.
To deal with this you have to check every data that you're converting if it really is a valid data. c# has many built-in methods/functions that will validate that and the one you should use is decimal.TryParse which ensures that data is valid for the type conversion.
Another thing is that you're using special format for your ToString ("C") which indicates that it should put currency mark in the string. You have to remember to then get rid of this.
Code explanation :
decimal IfValueIsConvertibleItWillBeHeldHere = 0;
if(decimal.TryParse(txt_cost.Text.Split(' ')[0], out IfValueIsConvertibleItWillBeHeldHere)
{
frm_BookingPg frm_HomePge = new frm_BookingPg(
cbo_Destination.Text,
cbo_AmountOfPeople.Text,
(int)IfValueIsConvertibleItWillBeHeldHere // see the difference ?
);
frm_HomePge.Show();
this.Hide();
}
else
{
// show some message to the user that input was invalid
}
Remarks :
Doing so leaves you with chaotic code because converting from decimal to int using explicit type conversion will trim that value. For example decimal d = 0.5M; explicitly converted to int like int i = (int)d; will return 0 because it trims down the part after decimal mark ..
You should rewrite your frm_BookingPg to accept decimal type instead of int type so that the value will be accurate :
public frm_BookingPg(string destination, string amountOfPeople, decimal cost)
Instead of your actual :
public frm_BookingPg(string destination, string amountOfPeople, int cost)
Have you tried replacing
Convert.ToInt32(txt_cost)
with just an int32 literal value?
As follows:-
frm_BookingPg frm_HomePge = new frm_BookingPg(cbo_Destination.Text, cbo_AmountOfPeople.Text, 1234);
does it still crash?
I am new to c# programming and I recently bumped into one problem which looks pretty basic.I store the string value like SV_1 in the variable lastServiceNo and split it using Split function and the result is stored in string array called index.Basically index[1] has some numeric value bt as string. now I want to convert string into int. In the following code , it behaves as expected until parse function is encountered.I could not understand why does this parse function returning 0 as index[1] has some numeric value in it. Can somebody point the problem please??
public string GenerateServiceNo() {
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return "SV_"+(lastIndex++).ToString();
}
int.Parse(string s) throws an exception if the number is too bug in terms of data size or the string "s" is not in the correct numerical format.
The format that this method accepts is "[ws][sign]number[ws]" where:
[ws] is optional for one or more whitespace(" ")
[sign] is optional for "+" or "-"
Check here for the full reference.
Thus said, I can assure you that if int.Parse(index[1]) returns 0 then that means index[1] equals "[ws][sign]0[ws]" using the transcript above.
However, looking at your code, I can conclude that you're incrementing a local variable after assignment without using its incremented value afterwards. Perhaps you meant that this operation shouldn't be 0?
If that's the case then I believe this is what you're trying to achieve:
public string GenerateServiceNo()
{
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return string.Format("SV_{0}", ++lastIndex);
}
Assuming index[1] == "0", this method will now return "SV_1".
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);