CultureInfo.GetCultureInfo Causing incorrect format error - c#

Everytime when I type in z as a input it fails. I don't understand what the problem is. It get the error " System.FormatException : Input string was not in a correct format" Dsales is a interger going into the converter to get converted into dollar and cents. Whats not correct about that?
using System;
using static System.Console;
using System.Globalization;
class HomeSales
{
static void Main()
{
string response;
int dsales = 0;
int esales = 0;
int fsales = 0;
int initial;
string damount;
string eamount;
string famount;
int damounti;
int eamounti;
int famounti;
WriteLine ("Enter a salesperson initial");
response = ReadLine();
//initial = Convert.ToInt32(response);
while (response == "d" || response == "D")
{
WriteLine ("Enter Line of sale");
damount = ReadLine();
damounti = Convert.ToInt32(damount);
dsales = dsales + damounti;
}
while (response == "z" || response == "Z")
{
WriteLine("Danielle sold {0}", dsales.ToString("C", CultureInfo.GetCultureInfo("en-US")));
}
}
}

You have incorrectly programmed your console loop.
Judging from your variable declarations and strings, your code intends to record sales amounts for different salespeople, reporting the total sale amount when sale entries are done.
The FormatException comes when you type "z" after the "Enter Line of Sale" prompt.
Instead of assuming that the user will always type a valid number, add a condition to check for a valid input before attempting to parse a number. The conditional check should also include the means to exit the loop early, or to at least avoid the code that parses a numerical value.
Also, as you're dealing with values interpreted as currency, consider using the System.Decimal (decimal) structure to store values, as calculations would be more accurate.

Related

Int32.TryParse C# - How to keep the last integer value

I'm trying to convert a string to int with
Int32.TryParse(input, out int number);
and I want to keep the last integer value.
E.g.
If string input = "123" then int number = 123 and if string input = "" or null then int number should stay 123 till input had a new string value.
Have someone a idea?
Keep a copy of the previous value, and if the parse failed copy it back in:
var previousValue = 1;
if(!int.TryParse(input, out var number))
{
number = previousValue;
}

Converting String Type to Currency in C#

I am trying to take the string input of TR and string PMP convert them into currency then multiply together to get an output in USD currency .
string SP; // Sales Price
string TR; //Total Revenue
string PMP; //Property management percentage
string PMF; //Property Management Monthly Fee
Console.WriteLine("What is the total rent revenue?");
TR = Console.ReadLine();
Console.WriteLine("what is the percentage you pay to property managment?");
PMP = Console.ReadLine();
Console.WriteLine("you will be buying {0}", PMF );
SP = Console.ReadLine();
TR = Console.ReadLine();
PMP = Console.ReadLine();
PMF = string.Format("{TR:C,PMP:C}") <------- THIS IS WHERE I AM TRYING TO CONVERT AND MULTIPLY****
Any help will be grateful. Thank you
PS I am not a programmer by trade (mostly Networking Engineering and Server Admin), This is my first 20 hours into programming.
If it were me, I would start by creating a method to get a valid decimal number from the user (because we do this several times, and it should have some error handling for cases when the user enters invalid entries). Something like:
public static decimal GetDecimalFromUser(string prompt,
string errorMessage = "Invalid entry. Please try again.")
{
decimal value;
while (true)
{
if (prompt != null) Console.Write(prompt);
if (decimal.TryParse(Console.ReadLine(), out value)) break;
if (errorMessage != null) Console.WriteLine(errorMessage);
}
return value;
}
Then, I would call this method to get the input from the user, do the required calculation (you didn't specify a formula, so I'm improvising), and output the value to the user:
decimal totalRevenue = GetDecimalFromUser("Enter the monthly rent revenue: $");
decimal propMgmtPct = GetDecimalFromUser("Enter the percentage you pay " +
"for property management: ");
decimal propMgmtFee = totalRevenue * propMgmtPct;
Console.WriteLine("The monthly property management fee will be: {0}",
propMgmtFee.ToString("C2", CultureInfo.CreateSpecificCulture("en-US")));
The Format syntax is more like string.Format("{0:C},{1:C}", TR, PMP).
You can only format numeric types such as decimal like that. Consider decimal.TryParse to see if what the user typed, looks like a number, then format the resulting number.
For multiplication you certainly need numeric types, like decimal, and you use the asterisk symbol * as the multiplication operator.

Converting string to double in C#

I have a long string with double-type values separated by # -value1#value2#value3# etc
I splitted it to string table. Then, I want to convert every single element from this table to double type and I get an error. What is wrong with type-conversion here?
string a = "52.8725945#18.69872650000002#50.9028073#14.971600200000012#51.260062#15.5859949000000662452.23862099999999#19.372202799999250800000045#51.7808372#19.474096499999973#";
string[] someArray = a.Split(new char[] { '#' });
for (int i = 0; i < someArray.Length; i++)
{
Console.WriteLine(someArray[i]); // correct value
Convert.ToDouble(someArray[i]); // error
}
There are 3 problems.
1) Incorrect decimal separator
Different cultures use different decimal separators (namely , and .).
If you replace . with , it should work as expected:
Console.WriteLine(Convert.ToDouble("52,8725945"));
You can parse your doubles using overloaded method which takes culture as a second parameter. In this case you can use InvariantCulture (What is the invariant culture) e.g. using double.Parse:
double.Parse("52.8725945", System.Globalization.CultureInfo.InvariantCulture);
You should also take a look at double.TryParse, you can use it with many options and it is especially useful to check wheter or not your string is a valid double.
2) You have an incorrect double
One of your values is incorrect, because it contains two dots:
15.5859949000000662452.23862099999999
3) Your array has an empty value at the end, which is an incorrect double
You can use overloaded Split which removes empty values:
string[] someArray = a.Split(new char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);
Add a class as Public and use it very easily like convertToInt32()
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
/// Summary description for Common
/// </summary>
public static class Common
{
public static double ConvertToDouble(string Value) {
if (Value == null) {
return 0;
}
else {
double OutVal;
double.TryParse(Value, out OutVal);
if (double.IsNaN(OutVal) || double.IsInfinity(OutVal)) {
return 0;
}
return OutVal;
}
}
}
Then Call The Function
double DirectExpense = Common.ConvertToDouble(dr["DrAmount"].ToString());
Most people already tried to answer your questions.
If you are still debugging, have you thought about using:
Double.TryParse(String, Double);
This will help you in determining what is wrong in each of the string first before you do the actual parsing.
If you have a culture-related problem, you might consider using:
Double.TryParse(String, NumberStyles, IFormatProvider, Double);
This http://msdn.microsoft.com/en-us/library/system.double.tryparse.aspx has a really good example on how to use them.
If you need a long, Int64.TryParse is also available: http://msdn.microsoft.com/en-us/library/system.int64.tryparse.aspx
Hope that helps.
private double ConvertToDouble(string s)
{
char systemSeparator = Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator[0];
double result = 0;
try
{
if (s != null)
if (!s.Contains(","))
result = double.Parse(s, CultureInfo.InvariantCulture);
else
result = Convert.ToDouble(s.Replace(".", systemSeparator.ToString()).Replace(",", systemSeparator.ToString()));
}
catch (Exception e)
{
try
{
result = Convert.ToDouble(s);
}
catch
{
try
{
result = Convert.ToDouble(s.Replace(",", ";").Replace(".", ",").Replace(";", "."));
}
catch {
throw new Exception("Wrong string-to-double format");
}
}
}
return result;
}
and successfully passed tests are:
Debug.Assert(ConvertToDouble("1.000.007") == 1000007.00);
Debug.Assert(ConvertToDouble("1.000.007,00") == 1000007.00);
Debug.Assert(ConvertToDouble("1.000,07") == 1000.07);
Debug.Assert(ConvertToDouble("1,000,007") == 1000007.00);
Debug.Assert(ConvertToDouble("1,000,000.07") == 1000000.07);
Debug.Assert(ConvertToDouble("1,007") == 1.007);
Debug.Assert(ConvertToDouble("1.07") == 1.07);
Debug.Assert(ConvertToDouble("1.007") == 1007.00);
Debug.Assert(ConvertToDouble("1.000.007E-08") == 0.07);
Debug.Assert(ConvertToDouble("1,000,007E-08") == 0.07);
In your string I see: 15.5859949000000662452.23862099999999 which is not a double (it has two decimal points). Perhaps it's just a legitimate input error?
You may also want to figure out if your last String will be empty, and account for that situation.

Sum up Double ReadLine values?

I'm new to C# programming and I'm not sure what I'm doing wrong because I can't sum up numbers that are Double. If I input 2,5 and 2,5 I get 5, but if I enter 2.5 and 2.5 I get zero when I use a dot instead of a comma between the numbers. Why this?
I add some of my code:
private void ReadInputAndSumNumbers()
{
while (!done)
{
Console.Write("Number: ");
if (double.TryParse(Console.ReadLine(), out num))
{
if (num == 0)
{
done = true;
}
else
{
sum += num;
}
}
}
}
My settings are to use a comma, but I would like the user to be able to enter a value with dot also
How are you converting your ReadLine input into Doubles? Most of the conversion operations are locale-specific, so if your Windows settings have , as the decimal separator, this setting is respected.
Example:
string enteredByUser = Console.ReadLine();
// uses user-specific Windows settings (decimal separator might be ",")
double myDouble1 = double.Parse(enteredByUser);
// uses default settings (decimal separator is always ".")
double myDouble2 = double.Parse(enteredByUser, CultureInfo.InvariantCulture);
A short side note: If you parse user input, you should look into double.TryParse, since this is more robust than double.Parse or Convert.ToDouble, since it allows you to detect faulty input without resorting to exception handling.
EDIT: If you want to support both comma and dot, you need to convert dots into commas (or vice versa) first. String.Replace can help you here. Note, though, that this approach will break if the user tries to enter a thousands separator (1.000,00 -> 1.000.00 or 1,000,00 -> error). The recommended way to do it is to
only accept the decimal separator specified in Windows, if the input comes from an end-user (i.e., keep your code as it is) and
only accept the neutral culture (.), if the input comes from some machine-generated output or file.
A sample for caculate the double sum
static void Main(string[] args)
{
var retVal = 0.0;
var sum = 0.0;
while (true)
{
Console.WriteLine("Enter input:");
string line = Console.ReadLine();
if (line == "exit")
{
break;
}
double.TryParse(line, NumberStyles.Any, CultureInfo.InvariantCulture, out retVal);
sum += retVal;
Console.WriteLine(string.Format("Double Value : {0}", sum ));
}
Console.ReadKey();
}

Char tryParse not working as I thought?

I have some problem with a method that I have done in c#. I'm trying to stop user from entering anything else then y and n. It's almost working that I want, but user can still enter more than one sign, and then it doesn't work! How can I do to also check if char is more than one char? I thought the tryParse solved that? Thanks!
// Method to check if item is food or not
private void ReadIfFoodItem()
{
Console.Write("Enter if food item or not (y/n): ");
if (char.TryParse(Console.ReadLine(), out responseFoodItem))
{
if(Char.IsNumber(responseFoodItem))
{
Console.WriteLine(errorMessage);
ReadIfFoodItem();
}
else
{
// Set true or false to variable depending on the response
if ((responseFoodItem == 'y' || responseFoodItem == 'Y'))
{
foodItem = true;
selectedVATRate = 12; // Extra variable to store type of VAT
}
else if ((responseFoodItem == 'n' || responseFoodItem == 'N'))
{
foodItem = false;
selectedVATRate = 25; // Extra variable to store type of VAT
}
else
{
Console.WriteLine(errorMessage);
ReadIfFoodItem();
}
}
}
}
The following code "works" in that it produces the expected results.
char responseFoodItem;
Console.Write("Enter if food item or not (y/n): ");
if (char.TryParse(Console.ReadLine(), out responseFoodItem))
{
// Set true or false to variable depending on the response
if ((responseFoodItem == 'y' || responseFoodItem == 'Y'))
{
Console.WriteLine("foodItem = true");
}
else if ((responseFoodItem == 'n' || responseFoodItem == 'N'))
{
Console.WriteLine("foodItem = false");
}
else
{
Console.WriteLine("Unrecognised input");
}
}
else
{
Console.WriteLine("Invalid input");
}
However, has others have pointed out using ReadKey is a better solution if you want to limit the input to a single key. It also means that the user doesn't have to press the Return/Enter key for the input to be accepted.
char represents a single character, so How can I do to also check if char is more than one char? I thought the tryParse solved that? seems a bit nonsensical... TryParse will try and parse a single character from your input and will explicitly fail if the value is null or has a length > 1.
Instead of checking a character, just check the string, e.g.:
string line = Console.ReadLine();
switch (line.ToUpperInvariant())
{
case "Y":
// Do work for y/Y
break;
case "N":
// Do work for n/N
break;
default:
// Show error.
break;
}
char.TryParse simply tries to parse the string supplied as an argument, it does not limit the number of characters that you can input to the console using Console.ReadLine.
When the user inputs more than a single character, char.TryParse will fail because the string returned by Console.ReadLine doesn't contain a single character.
You should use Console.Read instead.
How can I do to also check if char is more than one char?
string line = Console.ReadLIne();
If(!string.IsNullOrEmpty(line) && line.Length > 1)
for reading a single char use Console.ReadChar() instead.
Console.ReadLine allows users to type a string of any length and press enter.
How can I do to also check if char is more than one char? I thought the tryParse solved that?
From the manual page:
Converts the value of the specified string to its equivalent Unicode character. A return code indicates whether the conversion succeeded or failed....The conversion fails if the s parameter is null or the length of s is not 1.
Have you tried using Console.ReadKey instead of ReadLine?
To check it the user has inserted more then one char you could check the string length instead of use Char.TryParse
......
private void ReadIfFoodItem()
{
string answer=string.empty;
Console.Write("Enter if food item or not (y/n): ");
answer=Console.ReadLine()
if (answer.lenght>=1))
{
//error
.......
}
...............
This answer should help you: How can I limit the number of characters for a console input? C#
The console does not limit the user input (well it does, but to 256 characters), nor does char.TryParse which doesn't do anything at all to limit the input length.
You can try using Console.ReadKey
It's just one keystroke for the user and you know there won't be more than one char.
Why not comparing to the input'ed string?
And why not simplifying the comparison?
using System.Linq;
private static string[] ValidAnswers = new string[]{ "y", "yes" };
// Method to check if item is food or not
private void ReadIfFoodItem() {
Console.Write("Enter if food item or not (y/n): ");
string ans = Console.ReadLine();
// Checks if the answer matches any of the valid ones, ignoring case.
if (PositiveAnswers.Any(a => string.Compare(a, ans, true) == 0)) {
foodItem = true;
selectedVATRate = 12; // Extra variable to store type of VAT
} else {
foodItem = false;
selectedVATRate = 25; // Extra variable to store type of VAT
}
}
Alternatively, as others said, you can use Console.ReadKey().
Use Console.ReadKey() to limit the amount of characters. To test whether you have a Y or an N then you can compare the ASCII codes or use a regular expression.

Categories