There is such a code for a simple currency converter. ( SOM is the currency of Kyrgyzstan)

using System; namespace modConvertUSDRU { class Program { static void Main(string[] args) { Console.WriteLine("Hello\n"); Console.WriteLine("Введите 1 если USD/SOM или 2 если SOM/USD"); double ENTER = Convert.ToDouble(Console.ReadLine()); switch (ENTER) { case 1: ConvrtRUUSD(); break; case 2: ConverUSDRU(); break; } } static void ConverUSDRU() { double convertUSRU; Console.WriteLine("Введите сумму в сомах: "); double RU = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("Введите курс USD: "); double USD = Convert.ToDouble(Console.ReadLine()); convertUSRU = RU / USD; Console.WriteLine("Сумма равна {0} $.", convertUSRU); } static void ConvrtRUUSD() { double convertUSRU; Console.WriteLine("Введите сумму в USD: "); double USDSUM = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("Введите курс USD: "); double USDK = Convert.ToDouble(Console.ReadLine()); convertUSRU = USDSUM * USDK; Console.WriteLine("Сумма равна {0} сом.", convertUSRU); } } } 

do not look at beauty is just an example!

The question is the following: Why when entering for example (16000) everything works when entering (16,000) too, but when entering (16.000) it gives this error

Unhandled Exception: System.FormatException: The input string was not correct.
at System.Number.ParseDouble (String value, NumberStyles options, NumberFormatInfo numfmt)
at modConvertUSDRU.Program.ConverUSDRU () in D: \ MailCloud \ C # \ CS2017WORK \ modConvertUSDRU \ Program.cs: line 32
at modConvertUSDRU.Program.Main (String [] args) in D: \ MailCloud \ C # \ CS2017WORK \ modConvertUSDRU \ Program.cs: line 20 *

I understand that there may be a conflict in some kind of exception or there is a conjecture in the conflict (string / double), but where I can not understand the error!

  • Switch works with integers. - Ismoil Muhammadiev
  • four
    The problem is that in one country it is customary to write numbers with an exact one, and in the other with a comma. C # also takes this into account and it will not stick a value with a period, for example, into an es culture, or a semicolon value into en culture. - EvgeniyZ
  • Well, I tried to exclude the Switch, but the result is the same! On point gives an error. - j. Atisto
  • j. Atisto is not the switch itself. You just need to remember what works with integers. - Ismoil Muhammadiev
  • Thank! I will remember! Well, well, where is the mistake !? - j. Atisto

1 answer 1

Your problem is that certain countries have their own standards. For example, America, they have feet, miles, and other unknown indicators for us. It is customary to count everything in meters, kilometers and other standard values ​​for us.

It is not strange, but the accepted standards for writing numbers are also different for many countries. Somewhere it is customary to divide the number with a comma (123,456), and somewhere for this a point (123.456) is used. The C # language in this regard is also a fan of checking everything with culture and, therefore, it will not allow you to translate the value with a dot, for example, with ES culture (well, or with EN culture you will not be able to translate the value with a comma.).

A couple of examples:

 Thread.CurrentThread.CurrentCulture = new CultureInfo("en"); Console.WriteLine(double.Parse("123.456")); Console.WriteLine(double.Parse("123,456")); 

The value with a dot was displayed correctly, but the value with a comma itself , simply threw back and issued 123456 .

 Thread.CurrentThread.CurrentCulture = new CultureInfo("es"); Console.WriteLine(double.Parse("123.456")); Console.WriteLine(double.Parse("123,456")); 

Here we have a value with a point - the point itself loses (123456), and the value with a comma is displayed as it should.

 Thread.CurrentThread.CurrentCulture = new CultureInfo("ru"); Console.WriteLine(double.Parse("123.456")); Console.WriteLine(double.Parse("123,456")); 

And in this variant we get the error System.FormatException: "Входная строка имела неверный формат." (on the line with a dot), because Russian culture does not perceive the dot.

So how to be in that case, if you need to pull out this and that value?

  1. We can indicate the culture explicitly:

     CultureInfo culture = new CultureInfo("en"); Console.WriteLine(double.Parse("123.456", culture)); 
  2. You can try to pre-specify the culture and in our string values ​​replace one character with another:

     Thread.CurrentThread.CurrentCulture = new CultureInfo("ru"); Console.WriteLine(double.Parse("123.456".Replace(".", ","))); Console.WriteLine(double.Parse("123,456")); 
  3. You can try to use this bike (the call will be GetDouble("123,456", 0) , 0 - the value if nothing has happened to translate)):

     public static double GetDouble(string value, double defaultValue) { //Пробуем получить значение в текущей культуре if (!double.TryParse(value, NumberStyles.Any, CultureInfo.CurrentCulture, out var result) && //Пробуем получить в en культуре !double.TryParse(value, NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) && //Пробуем получить в нейтральной культуре !double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) { result = defaultValue; //Значение, если нечего не вышло } return result; } 
  4. Alternatively, it is to set the NumberDecimalSeparator value, which is actually responsible for the character used in the culture:

     var clone = (CultureInfo)CultureInfo.InvariantCulture.Clone(); clone.NumberFormat.NumberDecimalSeparator = "."; Console.WriteLine(double.Parse("123.456", clone)); Console.WriteLine(double.Parse("123,456")); //Или NumberFormatInfo format = new NumberFormatInfo {NumberDecimalSeparator = "."}; Console.WriteLine(double.Parse("123.456", format)); Console.WriteLine(double.Parse("123,456")); 

In general, try. Good luck!

  • one
    And where is the easiest option - to transfer the desired culture in double.Parse? - Pavel Mayorov
  • @PavelMayorov I think this is an obvious option, but you are right, I’ll add it now. - EvgeniyZ
  • I did this: 'double RU = Convert.ToDouble (Console.ReadLine (). Replace ('. ',', ')); 'Dc` everything works fine! - j. Atisto
  • four
    For using Replace in such cases, I would tear off my hands. You don't have enough culture-multur! - Alexander Petrov
  • one
    @ j.Atisto: .Replace('.', ',') - very bad. Because the comma is a valid thousands separator in the English locale. Why do wrong when you can do right? - VladD