Разбор строк удваивается запятой и точкой

Я пытаюсь написать функцию, которая в основном преобразует массив строк в массив строк, где все парные числа в массиве округлены до числа десятичных чисел, которые я задал. Также могут быть строки в массиве, которые вообще не являются двойными значениями.

string[,] values = new string[1, 3]; values[0, 0] = "hello"; values[0, 1] = "0.123"; values[0, 2] = "0,123"; int decimalPlaces = 2; double tmp; string format = "F" + decimalPlaces.ToString(); IFormatProvider provider = CultureInfo.InvariantCulture; for (int i = 0; i < values.GetLength(0); i++) { for (int j = 0; j < values.GetLength(1); j++) { if (double.TryParse(values[i, j], out tmp)) { values[i, j] = tmp.ToString(format, provider); } } } Console.ReadLine(); 

Результат должен быть: «привет», «0.12», «0.12», но это «привет», «123.00», «0.12» будет обрабатывать запятую неправильно. У кого-нибудь есть простое и эффективное решение для этого?

Вы хотите обработать точку ( . ) Как запятую ( , ). Итак, замените

 if (double.TryParse(values[i, j], out tmp)) 

с

 if (double.TryParse(values[i, j].Replace('.', ','), out tmp)) 

Лечить и то, и другое. в качестве десятичной точки вы должны не только заменить ее на другую, но также убедиться, что используемый синтаксический анализ Culture интерпретирует ее как десятичную точку.

 text = text.Replace(',', '.'); return double.TryParse(text, NumberStyles.Any, CultureInfo.InvariantCulture, out value); 

ВАМ НЕОБХОДИМО заменить запятую и точку.

У меня была такая же проблема. Причина проста, культура конверсии играет большую роль, в которой интерпретируется запятая или точка. Я использую немецкую культуру, где запятая отличает фракции, где, как и везде, точка выполняет эту работу.

Здесь я сделал полный пример, чтобы понять разницу.

 string[] doubleStrings = {"hello", "0.123", "0,123"}; double localCultreResult; foreach (var doubleString in doubleStrings) { double.TryParse(doubleString, NumberStyles.Any, CultureInfo.CurrentCulture, out localCultreResult); Console.WriteLine(string.Format("Local culture results for the parsing of {0} is {1}",doubleString,localCultreResult)); } double invariantCultureResult; foreach (var doubleString in doubleStrings) { double.TryParse(doubleString, NumberStyles.Any, CultureInfo.InvariantCulture, out invariantCultureResult); Console.WriteLine(string.Format("Invariant culture results for the parsing of {0} is {1}", doubleString, invariantCultureResult)); } 

результаты, в которых введите описание изображения здесь

Играйте с культурой, и вы получите результат, который вам нужен.

Проблема в том, что вы (или система) не можете отличить десятичный разделитель от разделителя тысяч, когда они могут быть как запятой, так и точкой. Например:

В моей культуре,

1.123 – нормальное обозначение для числа выше 1000; в то время как

1,123 – число вблизи 1.

Использование инвариантной культуры по умолчанию использует точку в виде десятичного разделителя. В общем, вы должны убедиться, что все числа написаны с использованием одной и той же постоянной культуры во всех системах (например, инвариантная культура).

Если вы уверены, что ваши цифры никогда не содержат ничего, кроме запятой или точкой для десятичного разделителя (т. String.Replace() Без разделителей тысяч), я бы String.Replace() запятую с точкой и остальное, как и вы.

В противном случае вам будет сложно программировать что-то, что может отличить 1.123 от 1,123 не зная культуры.

Расширение для parsingа десятичного числа из строки.

  • Независимо от того, будет ли это число в начале, в конце или в середине строки.
  • Независимо от того, будет ли только количество или много «мусорных» писем.
  • Независимо от того, какой разделитель сконфигурирован в культурных настройках на ПК: он будет правильно разобрать точку и запятую.
  • Возможность установки десятичного символа вручную.

     public static class StringExtension { public static double DoubleParseAdvanced(this string strToParse, char decimalSymbol = ',') { string tmp = Regex.Match(strToParse, @"([-]?[0-9]+)([\s])?([0-9]+)?[." + decimalSymbol + "]?([0-9 ]+)?([0-9]+)?").Value; if (tmp.Length > 0 && strToParse.Contains(tmp)) { var currDecSeparator = System.Windows.Forms.Application.CurrentCulture.NumberFormat.NumberDecimalSeparator; tmp = tmp.Replace(".", currDecSeparator).Replace(decimalSymbol.ToString(), currDecSeparator); return double.Parse(tmp); } return 0; } } 

Как использовать:

 "It's 4.45 O'clock now".DoubleParseAdvanced(); // will return 4.45 "It's 4,45 O'clock now".DoubleParseAdvanced(); // will return 4.45 "It's 4:45 O'clock now".DoubleParseAdvanced(':'); // will return 4.45 

Вы можете проверить, содержит ли строка десятичную точку, используя

string s="";

  if (s.Contains(',')) { //treat as double how you wish } 

а затем рассматривать это как десятичное, иначе просто передайте недвойное значение вдоль.

Используйте эту перегрузку double.TryParse, чтобы указать разрешенные форматы:

Метод Double.TryParse (String, NumberStyles, IFormatProvider, Double%)

По умолчанию double.TryParse будет анализироваться на основе существующих форматов культуры.

попробуйте это … это работает для меня.

 double vdouble = 0; string sparam = "2,1"; if ( !Double.TryParse( sparam, NumberStyles.Float, CultureInfo.InvariantCulture, out vdouble ) ) { if ( sparam.IndexOf( '.' ) != -1 ) { sparam = sparam.Replace( '.', ',' ); } else { sparam = sparam.Replace( ',', '.' ); } if ( !Double.TryParse( sparam, NumberStyles.Float, CultureInfo.InvariantCulture, out vdouble ) ) { vdouble = 0; } } 
  • Win32 - чтение с stdin с таймаутом
  • Как подключиться к библиотеке с помощью Code :: Blocks?
  • Как обрабатывать событие click в столбце Button в Datagridview?
  • dynamic_cast из "void *"
  • Как вы тестируете ASP.NET Core MVC Controllers, которые возвращают анонимные объекты?
  • Макрос макросов макросов
  • Откуда происходят сбои «чистой виртуальной функции»?
  • Доступ к определенному значению RGB пикселя в openCV
  • Получить домен хоста из URL?
  • целочисленная проверка ввода, как?
  • C # эквивалентно charAt ()?
  • Давайте будем гением компьютера.