Calling .ToString() on a string to change its format - c#

In order to be able to dynamically change a value in my application I am storing it in the resx file. Of course this is a string.
MaximumSpend - 5000
In my code I do int.Parse(MyApp.MaximumSpend). Now I can change the max spend in one place and the application handles it with no futher changes.
In the front end I want to show the value as $5,000.
If this were an int, I would do
MyInt.ToString("0#,##0")
But it is already a string. I could convert to an int and then call .ToString() on it but that seems wasteful.
Is there a much better way of changing 5000 to 5,000 in my front end code? Or is changing to an int and back the best way?
UPDATE: Thanks everyone. I've gone ahead and done the int.parse and back to a string.
$('#MaximumSpend').text("#int.Parse(MyResources.MyNamespace.MaximumSpend).ToString("##,###")");
I'll be using the web.config for this in the future (I've already done that for other items, just not these which started as a purely front-end thing then I decided to use it in the backend).
I have upvoted accordingly

Resx files are not configuration files. They are meant to store static resources, like localized strings, images, and so on.
What you probably want is a Setting, which is two tabs down in the Visual Studio properties. There you can define an application-scoped setting which is typed to be an int, and it will generate a strongly typed accessor. No parsing required*.
Properties.Settings.Default.MyInt.ToString("0#,##0");
Here's some more information on the subject: Using Settings in C#.
* Technically, it's still parsed, but .NET does it for you.

Just clone a en-US culture (which uses $ as a CurrencySymbol), set it's CurrencyDecimalDigits to 0 and format your number with The "C" format specifier and that cloned culture as;
int i = 5000;
var clone = (CultureInfo)CultureInfo.GetCultureInfo("en-US").Clone();
clone.NumberFormat.CurrencyDecimalDigits = 0;
Console.WriteLine(i.ToString("C", clone)); // $5,000
EDIT: Looks like you have a string "5000" in first place, you need to parse it first to int with int.Parse and then can use that integer value to generate specific formatted string.
int i = int.Parse("5000");
...
...

The short answer is: no, there's no better way
The long answer is:
You could parse the string and convert it, but it'd probably be way worse than just converting to int, then back to string with formatting.
You could just store the value in your resource as an integer directly, instead of as an string. The designer doesn't allow you to directly do it, but you can open the .resx file with a text editor (or in Visual Studio, right click on it, Open With and select the XML Text Editor), and add your resource on the correct section, like this:
<data name="MaximumSpend" xml:space="preserve" type="System.Int32, mscorlib">
<value>5000</value>
</data>
Afterwards, you can view it on the normal resource editor (you'll see your value in the Other section. You can even edit it, just not "add more")
Or:
Use a settings file, instead of a resource, which probably makes more sense for this kind of data

I think changing from an int and back to a string is perhaps the best way. For example:
string strIntString = strMaxSpend.Split("-").Trim();
int nValue;
if (!Int32.TryParse(strIntString, out nValue))
{
//Parse failed
}
Note I use TryParse instead of a straight Convert call incase the conversion fails so we can fail smoothly.
Then just doing the ToString() part as mentioned in your question.

Try This :
string s = "2342314854";
string s1 = string.Format("{0:C}", Double.Parse(s));
Result will be : $2,342,314,854.00
this code will work to convert string value into currency.

Related

Design better text file format for reading mixed type data of variable length

I am designing a text file format to be read in C#. I have a need to store types: int, double and string on a single line. I'm planning to use a .CSV format so the file can be manually opened and read. A particular record may have say 8 known types, then a variable number of "indicator" combinations of either (string, int, double) or (string, int, double, double), and some lines may include no "indicators". Thus, each record is may be of variable length.
In VB6 I would just input the data, split the data, into a variant array, then determine the number of elements on that line in the array, and use the ***VarType function to determine if the final "indicator" variables are string, int, or double and parse the field accordingly.
There may be a better way to design a text file and that may be the best solution. If so I'm interested in hearing ideas. I have searched but found no questions that specifically talk about reading variable length lines of text with mixed type into C#.
If a better format is not forthcoming, is there a way to duplicate the VB6 VarType function within C# as described two paragraphs above***? I can handle the text file reading and line splitting easily in C#.
you could use either json or xml as they are well supported in .NET and have automatic serialization capabilities
First I agree with Keith's suggestion to use Xml or JSON. You are reinventing a wheel here. This page has an introductory example of how to serialize objects to a file and some links to more info.
If you need to stick with your own file format and custom serialization/deserialization however take a look at the Convert class, as well as the various TryParse methods which hang off of the intrinsic value types like int and double.

How to convert sql type double-precision in c#

I have a database access, and one of this field is double-precision.
Normally if i set in the textbox 1.71 or 1,71 the field in database should contain 1.71.
But if i execute query the value of acces'field is 171 !!.
public const string QUERY =
#"UPDATE TBLART
SET TBLART.COST = #cost
WHERE TBLART.CODE= '1'";
var param = new DynamicParameters();
var cost = totalCost.Replace(',', '.'); //totalCost is a textbox
param.Add("cost", Double.Parse(cost), DbType.Double);
gsmconn.Execute(QUERY, param);
What i wrong ? Thanks.
double.Parse will use the current thread's culture by default. I suspect your current culture uses "." as a grouping separator.
Two options:
Continue to use Replace as you are already doing, but then specify CultureInfo.InvariantCulture when parsing
Remove the replacement, and just use the current thread's culture when parsing the original value. This relies on the culture being appropriate for the user, but is probably a better solution when that's the case. (Otherwise someone entering "1,234.56" will get a parse error when they expected a value of "just a bit more than 1234".)
If I remember correctly in windows forms you can bind an double property to a textbox and it will automatically take care of parsing and converting. You should not manually do parsing from string to double.
That problem is already solved fro you by the .NET framework.
Another suggestion, your data access code should not do any parsing. That should be done in some higher layer. But better leave it to the framework.

c# : Loading typed data from file without casting

Is there a way to avoid casting to a non-string type when reading data from a text file containing exclusively integer values separated by integer markers ('0000' for example) ?
(Real-Life example : genetic DNA sequences, each DNA marker being a digit sequence.)
EDIT :
Sample data : 581684531650000651651561156843000021484865321200001987984948978465156115684300002148486532120000198798400009489786515611568430000214848653212000019879849480006516515611684531650000651651561156843000021 etc...
Unless I use a binary writer and read bytes, rather than text (because that is how data written at first), I think this a funky idea, so "NO" would be the straight answer for this.
Just wanted to get a definitive confirmation to that here, just to be definitely sure.
I welcome any intermediate solution to write/read this kind of data efficiently without having to code a custom reader GUI to display it outside my app, intelligibly (in some generic reader/viewer).
The short answer is no, because a text file is a string of characters.
The long answer is sort of yes; if you put your data into a format like XML, a deserializer can implicitly cast the data back to the correct type (without you having to do it manually) based on your schema.
If you have control over the format, consider using a binary format for your file and use e.g. BinaryReader.ReadInt32.
rather then just casting, you really should use the .TryParse(...) method(s) of the types you are trying to read. This is a much more type-safe solution.
And to answer your question, other then using a binary file, there is not (to my knowledge) a way to do this without casting (or using the TryParse methods)
The only way to control all the read process is to read bytes. Else you read strings.
Edit : I Didn't talk about automatic serialization via XML because of the details on the file format you gave.
If the data is text and you need to access it as an integer, a conversion will be required. The only question is which code does the conversion.
Depending upon the file format, you could look for classes or libraries that already handle them. Otherwise, keep your code well organized so you don't have to pay attention to the conversion too much.
Some options:
// Could throw exceptions
var x = Convert.ToInt32(text);
var x = Int32.Parse(text);
// Won't throw an exception, just check the results
int x = 0;
if (Int32.TryParse(text, out x)) { ... }

How to read a text file into a List in C#

I have a text file that has the following format:
1234
ABC123 1000 2000
The first integer value is a weight and the next line has three values, a product code, weight and cost, and this line can be repeated any number of times. There is a space in between each value.
I have been able to read in the text file, store the first value on the first line into a variable, and then the subsequent lines into an array and then into a list, using first readline.split('').
To me this seems an inefficient way of doing it, and I have been trying to find a way where I can read from the second line where the product codes, weights and costs are listed down into a list without the need of using an array. My list control contains an object where I am only storing the weight and cost, not the product code.
Does anyone know how to read in a text file, take in some values from the file straight into a list control?
Thanks
What you do is correct. There is no generalized way of doing it, since what you did is that you descirbed the algorithm for it, that has to be coded or parametrized somehow.
Since your text file isn't as structured as a CSV file, this kind of manual parsing is probably your best bet.
C# doesn't have a Scanner class like Java, so what you wan't doesn't exist in the BCL, though you could write your own.
The other answers are correct - there's no generalized solution for this.
If you've got a relatively small file, you can use File.ReadAllLines(), which will at least get rid of a lot cruft code, since it'll immediately convert it to a string array for you.
If you don't want to parse strings from the file and to reserve an additional memory for holding split strings you can use a binary format to store your information in the file. Then you can use the class BinaryReader with methods like ReadInt32(), ReadDouble() and others. It is more efficient than read by characters.
But one thing: binary format is bad readable by humans. It will be difficult to edit the file in the editor. But programmatically - without any problems.

Should we store format strings in resources?

For the project that I'm currently on, I have to deliver specially formatted strings to a 3rd party service for processing. And so I'm building up the strings like so:
string someString = string.Format("{0}{1}{2}: Some message. Some percentage: {3}%", token1, token2, token3, number);
Rather then hardcode the string, I was thinking of moving it into the project resources:
string someString = string.Format(Properties.Resources.SomeString, token1, token2, token3, number);
The second option is in my opinion, not as readable as the first one i.e. the person reading the code would have to pull up the string resources to work out what the final result should look like.
How do I get around this? Is the hardcoded format string a necessary evil in this case?
I do think this is a necessary evil, one I've used frequently. Something smelly that I do, is:
// "{0}{1}{2}: Some message. Some percentage: {3}%"
string someString = string.Format(Properties.Resources.SomeString
,token1, token2, token3, number);
..at least until the code is stable enough that I might be embarrassed having that seen by others.
There are several reasons that you would want to do this, but the only great reason is if you are going to localize your application into another language.
If you are using resource strings there are a couple of things to keep in mind.
Include format strings whenever possible in the set of resource strings you want localized. This will allow the translator to reorder the position of the formatted items to make them fit better in the context of the translated text.
Avoid having strings in your format tokens that are in your language. It is better to use
these for numbers. For instance, the message:
"The value you specified must be between {0} and {1}"
is great if {0} and {1} are numbers like 5 and 10. If you are formatting in strings like "five" and "ten" this is going to make localization difficult.
You can get arround the readability problem you are talking about by simply naming your resources well.
string someString = string.Format(Properties.Resources.IntegerRangeError, minValue, maxValue );
Evaluate if you are generating user visible strings at the right abstraction level in your code. In general I tend to group all the user visible strings in the code closest to the user interface as possible. If some low level file I/O code needs to provide errors, it should be doing this with exceptions which you handle in you application and consistent error messages for. This will also consolidate all of your strings that require localization instead of having them peppered throughout your code.
One thing you can do to help add hard coded strings or even speed up adding strings to a resource file is to use CodeRush Xpress which you can download for free here: http://www.devexpress.com/Products/Visual_Studio_Add-in/CodeRushX/
Once you write your string you can access the CodeRush menu and extract to a resource file in a single step. Very nice.
Resharper has similar functionality.
I don't see why including the format string in the program is a bad thing. Unlike traditional undocumented magic numbers, it is quite obvious what it does at first glance. Of course, if you are using the format string in multiple places it should definitely be stored in an appropriate read-only variable to avoid redundancy.
I agree that keeping it in the resources is unnecessary indirection here. A possible exception would be if your program needs to be localized, and you are localizing through resource files.
yes you can
new lets see how
String.Format(Resource_en.PhoneNumberForEmployeeAlreadyExist,letterForm.EmployeeName[i])
this will gave me dynamic message every time
by the way I'm useing ResXManager

Categories

Resources