Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Андрей Игоревич
Member

Откуда:
Сообщений: 95
Есть программа, хорошо работает. Переношу экзешник на другую систему - не работает. Долго и занудно искал ошибку, нашел:
В одной системе FloatToStr преобразует текст с запятой в число без проблем, а в другой выдаёт ошибку
автор
'-0,59' is not a valid floating point value

Если менять заменять точку при считывании - во второй системе всё работает, в первой нет - как это можно аккуратно обыграть (ну я понимаю, что можно через костыль, типа в случае ошибки считывания менять одно на другое и считывать заново, но костыли - зло), наверняка есть способ попроще.

А вообще, что удивительно, до определённого момента всё работало на обеих системах, а потом хоп и перестало (знак разделителя в системе сам не менял, но комп рабочий, может админы чего намудрили).
3 сен 18, 10:11    [21662333]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
DarkMaster
Member

Откуда: Donetsk,Ukraine
Сообщений: 6033
Андрей Игоревич,

FormatSettings
3 сен 18, 10:14    [21662335]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45680

Андрей Игоревич
В одной системе FloatToStr преобразует текст с запятой в число без проблем

FloatToStr годится только для строк, которые вводит пользователь в соответствии с его
пользовательскими настройками. Если ты откуда-то берёшь строку фиксированного формата, то
к ней надо применять функции преобразования с фиксированным форматом. Например, Val().

Posted via ActualForum NNTP Server 1.5

3 сен 18, 12:45    [21662526]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Андрей Игоревич
Member

Откуда:
Сообщений: 95
DarkMaster,

Спасибо:
FormatSettings.DecimalSeparator:='.';
3 сен 18, 13:18    [21662570]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Андрей Игоревич
Member

Откуда:
Сообщений: 95
Андрей Игоревич,

Точнее наоборот
FormatSettings.DecimalSeparator:=',';
3 сен 18, 13:19    [21662571]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 12230
Андрей Игоревич
Точнее наоборот


нужно сделать 2 варианта замены
Андрей Игоревич
FloatToStr преобразует текст с запятой в число без проблем, а в другой выдаёт ошибку


  val := StringReplace(val, ',', FormatSettings.DecimalSeparator, []);
  val := StringReplace(val, '.', FormatSettings.DecimalSeparator, []);


т.е. чтобы не гадать, что там у пользователя, можно и точку, и запятую заменить на "FormatSettings.DecimalSeparator"
3 сен 18, 13:27    [21662585]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Андрей Игоревич
Member

Откуда:
Сообщений: 95
X11,

Спасибо, так и сделаю.
3 сен 18, 13:29    [21662590]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10488
X11
нужно сделать 2 варианта замены
Не нужно. Если данные формируются в этой системе, то используем дефолтный разделитель. Если приходят снаружи, то используем разделитель согласно протокола
3 сен 18, 13:34    [21662601]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Василий 2
Member

Откуда:
Сообщений: 189
X11
нужно сделать 2 варианта замены
  val := StringReplace(val, ',', FormatSettings.DecimalSeparator, []);
  val := StringReplace(val, '.', FormatSettings.DecimalSeparator, []);


т.е. чтобы не гадать, что там у пользователя, можно и точку, и запятую заменить на "FormatSettings.DecimalSeparator"

Борланд научил плохому, а все и рады потакать дурным привычкам. FormatSettings как глобальную переменную надо избегать всеми силами кроме тех случаев, когда она используется по назначению - как текущие региональные настройки. Да и то, глобальная переменная - зло, и более правильно TFormatSettings.Create('') непосредственно перед применением.
Потому как:
1) Некая библиотека глубоко внутри себя сменила DecimalSeparator на что-то свое, и не вернула прежнее значение.
1.1) Некая библиотека глубоко внутри себя сменила DecimalSeparator на что-то свое, и не успела вернуть прежнее значение, как из другого потока выполняется обращение к этому полю
2) Программа запущена, юзер сменил региональные настройки. FormatSettings содержит старые значения.
и т.д.

В общем, я советую так (к чему пришел на своем опыте):
1) Float/DateToStr, Format без параметра типа TFormatSettings - только для отображения, да и то осмысленно
2) Во всех остальных случаях - фиксированный экземпляр TFormatSettings, с жестко прописанными полями. В качестве основы можно взять, например, LOCALE_INVARIANT.
3 сен 18, 15:14    [21662794]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4326
Андрей Игоревич
Андрей Игоревич,

Точнее наоборот
FormatSettings.DecimalSeparator:=',';


Когда пользуетесь настройкой глобального FormatSettings не забывайте о:

Application.UpdateFormatSettings:=False;


А то вы рискуете огрести проблем.
3 сен 18, 15:31    [21662814]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Соколинский Борис
Member

Откуда: Москва
Сообщений: 8168
_Vasilisk_
X11
нужно сделать 2 варианта замены
Не нужно. Если данные формируются в этой системе, то используем дефолтный разделитель. Если приходят снаружи, то используем разделитель согласно протокола

У меня другие рекомендации
1. системные настройки формата использовать только для вывода на экран/конвертации пользовательского ввода
2. для файловых операций использовать стандартизованные (протокольные)
3. чтобы не было коллизий вспомнить про третий параметр функций.
3 сен 18, 16:26    [21662877]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 3651
rgreat
Андрей Игоревич
Андрей Игоревич,

Точнее наоборот
FormatSettings.DecimalSeparator:=',';


Когда пользуетесь настройкой глобального FormatSettings не забывайте о:

Application.UpdateFormatSettings:=False;


А то вы рискуете огрести проблем.

Она локальная, и стртуфлоат принимает вторым параметром.
3 сен 18, 16:52    [21662908]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 3651
JaDi,

в нормальных делфях, естественно.
3 сен 18, 16:52    [21662910]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4326
JaDi
Она локальная

Да ну?

unit System.SysUtils;

<..>

var
  // Note: Using the global FormatSettings formatting variables is not thread-safe.
  FormatSettings: TFormatSettings;


JaDi
и стртуфлоат принимает вторым параметром.
FloatToStr и без 2-го параметра бывает.
Причем если проект разрабатывается нормально (без бардака), то проще использовать именно такой.
3 сен 18, 17:53    [21662988]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 3651
rgreat
JaDi
и стртуфлоат принимает вторым параметром.
FloatToStr и без 2-го параметра бывает.
Причем если проект разрабатывается нормально (без бардака), то проще использовать именно такой.

О да, результат использования без форматсеттинга прекрасно виден в этом самом топике.
3 сен 18, 18:25    [21663020]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4326
JaDi
О да, результат использования без форматсеттинга прекрасно виден в этом самом топике.
Трудно-ли умеючи? (с)
3 сен 18, 18:45    [21663040]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 3651
rgreat,

так-так, чуствую, далее пойдет предложение следить за компами пользователей и их настройками :D
3 сен 18, 18:58    [21663044]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4326
Делай так.

Application.UpdateFormatSettings:=False;
FormatSettings.DecimalSeparator:='.';


И можешь не следить.
3 сен 18, 19:01    [21663049]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4326
Но особо огороженные граждане могут каждый раз генерить свою копию FormatSettings.

Разрешаю.
3 сен 18, 19:02    [21663052]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Соколинский Борис
Member

Откуда: Москва
Сообщений: 8168
rgreat
Но особо огороженные граждане могут каждый раз генерить свою копию FormatSettings.
Зачем каждый раз?
Одного экземпляра для всех файловых операций вполне достаточно. А переключение дефолтного рано или поздно непременно приведет к косякам. Например в многопоточном приложении.
3 сен 18, 20:57    [21663128]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4326
Соколинский Борис
А переключение дефолтного рано или поздно непременно приведет к косякам. Например в многопоточном приложении.
Зачем его вообще переключать?
Один раз выставил как надо при старте и радуйся.

Делать разные разделители в разных местах приложения - это либо явный bad design, либо исключение без которого никак не обойтись, но тут уже не зазорно и локальный TFormatSetting поюзать.
3 сен 18, 21:18    [21663145]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Соколинский Борис
Member

Откуда: Москва
Сообщений: 8168
rgreat
Зачем его вообще переключать?
Затем, что в UI должны быть системные настройки, а в файле стандартизованные.
3 сен 18, 22:34    [21663206]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Котовасия
Member

Откуда:
Сообщений: 269
Соколинский Борис
rgreat
Зачем его вообще переключать?
Затем, что в UI должны быть системные настройки, а в файле стандартизованные.

Ой да ладно, "должны".
Мы во всех приложениях при старте выставляем единые настройки формата, а дальше пользуйся чем бог на душу положит, все равно десятичный разделитель - всегда точка, а дата - всегда только вот в таких форматах, невзирая на системные настройки, и никто никогда ни разу не жаловался, а наоборот. Может быть, когда начнем англичанам софт продавать, формат даты будем системный использовать, а в России и так сойдет.
3 сен 18, 22:51    [21663227]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4326
Соколинский Борис
Затем, что в UI должны быть системные настройки
Нефиг.
Как минимум не в корпоративном ПО.
3 сен 18, 22:53    [21663232]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4326
Разделитель целого и дробного - "точка" и баста!
3 сен 18, 22:53    [21663233]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить