Как безопасно и правильно конвертировать число из пользовательского ввода в двойное? - PullRequest
4 голосов
/ 05 января 2012

Это, в основном, проблема CultureInfo. Формально в моей стране десятичный разделитель - это запятая (,), а разделитель тысяч - это точка (.). На практике, однако, это используется только бухгалтерами и прилежными людьми. Обычно люди никогда не используют разделитель тысяч, и они используют как запятую, так и точку взаимозаменяемо в качестве десятичного разделителя. Я видел эту проблему даже в некоторых электронных таблицах Excel, которые я получал от других людей, поскольку Excel не распознал точку как десятичный разделитель, оставляя поле в формате строки, а не числа.

Мое "решение" до сих пор состояло в том, чтобы просто заменить все запятые в пользовательском вводе на точки, а затем проанализировать двойник с InvariantCulture, например так:

string userInput;
...
userInput = userInput.Replace(',', '.');
double result;
double.TryParse(userInput, NumberStyles.Float, CultureInfo.InvariantCulture, out result);

Очевидно, что это потерпит неудачу, когда кто-то действительно войдет в разделитель тысяч, и это больше похоже на взлом, чем на реальное решение. Итак, кроме создания собственного парсера для парных чисел, есть ли более понятные способы решения этой проблемы?

Ответы [ 2 ]

2 голосов
/ 05 января 2012

Если вы используете ASP.Net, вы можете использовать AjaxControlToolkit FilteredTextBox , вы также можете выполнить задачу, используя регулярные выражения и сопоставление с образцом. Почти всегда лучше попытаться получить стандартный ввод, чем пытаться иметь дело со всеми возможными человеческими входными переменными.

Некоторые другие ссылки:
MaskedTextBox
Инструменты WPF FilteredTextBox

1 голос
/ 05 января 2012

Если есть правила, которые могут окончательно определить, что они имели в виду, тогда вы можете закодировать логику. С этой проблемой, однако, невозможно узнать намерение в каждом случае:

1,001 === 1.001 or 1001

Кроме того, даже если любая «лучшая» логика может предполагать, что числа типа «1,01» однозначны, такая запись может быть опечаткой «1,001». Насколько это вероятно, зависит от того, какие данные вы собираете.

Если люди редко используют разделитель тысяч, то ваша логика кажется хорошей. Однако если вы хотите быть на 100% уверены в своих намерениях, единственный способ убедиться в этом - спросить их, что они имеют в виду в таких случаях. Например. если кто-то вводит 1,001 или 1.001, то не проходит проверку, но перекодирует его как «1,001.0» (или .00, если имеет дело с валютой), чтобы устранить неоднозначность, вынуждая его пересмотреть его.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...