Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 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
Сообщений: 6081
Андрей Игоревич,

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

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

Андрей Игоревич
В одной системе 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
Сообщений: 12480
Андрей Игоревич
Точнее наоборот


нужно сделать 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

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

Откуда:
Сообщений: 238
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

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

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


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

Application.UpdateFormatSettings:=False;


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

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

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

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

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


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

Application.UpdateFormatSettings:=False;


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

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

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

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

Откуда:
Сообщений: 4481
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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

Откуда:
Сообщений: 4481
Разделитель целого и дробного - "точка" и баста!
3 сен 18, 22:53    [21663233]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Котовасия
Member

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

лапочка ты наш.
3 сен 18, 22:57    [21663236]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Василий 2
Member

Откуда:
Сообщений: 238
Для программ со скрипом еще допустимо юзать FormatSettings. Но только при условии, что все библиотеки ведут себя порядочно и сами FormatSettings не касаются. Да и то возможны накладки.
Однако за наводку на UpdateFormatSettings спасибо, не знал. Стало быть, предусмотрен подхват смены значений юзером.
4 сен 18, 11:43    [21663699]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4481
Василий 2
возможны накладки.
Расскажи мне для общего образования причины возможныхвлзможны накладок?

Но окромя явных ошибок програмстов в собственном коде.
4 сен 18, 14:31    [21664069]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Василий 2
Member

Откуда:
Сообщений: 238
rgreat
Василий 2
возможны накладки.
Расскажи мне для общего образования причины возможныхвлзможны накладок?

Но окромя явных ошибок програмстов в собственном коде.

Ну например, использование переменной может произойти до ее высечения в мраморе. Некий модуль может быть иниц-н раньше. Т.е. порядок юзанья юнитов должен быть регламентирован, а это слабое звено, т.к. не контролируется компилятором. Или другой вариант - кто-то может забыться и временно поменять поле записи. В коллективной разработке с кучей прогеров, да еще и не одного "поколения" вполне вероятно упустить такие детали.
Так что "если б я была царица", и если уж никак не обойтись без глобальной переменной, я бы рекомендовал завести собственную константу и иниц-ть ее через хак по указателю. Таким образом точно будет страховка от влияния библиотек раз и защита от ненамеренной модификации два.
4 сен 18, 14:56    [21664114]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4481
Василий 2,
автор
Ну например, использование переменной может произойти до ее высечения в мраморе. Некий модуль может быть иниц-н раньше.
Мы говорим не абстрактную глобальную переменную а про вполне конкретную из System.SysUtils, иннициализируемую в нем же в разделе initialization.

Как она может быть не иннициализированой при ее использовании? ;)

автор
забыться и временно поменять

Это просто ошибка програмиста, которая может быть где угодно.

автор
В коллективной разработке с кучей прогеров, да еще и не одного "поколения" вполне вероятно упустить
За такое надо бить, и можно даже ногами.
Менять глобальный FormatSettings в процессе работы ПО - это из разряда стрельбы себе (и соседям) в ногу.

автор
рекомендовал завести собственную константу и иниц-ть ее через хак по указателю

Не-не-не, Девид Блейн, я лучше по старинке. ;)
4 сен 18, 18:40    [21664555]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Gator
Member

Откуда: Москва
Сообщений: 13909
rgreat,

Не-не-не. Фигня эта всё про DecimalSeparator и остальное. Есть СТАНДАРТ, конвенции, от них и надо плясать.

https://ru.wikipedia.org/wiki/Открытый_формат
https://ru.wikipedia.org/wiki/Формат
5 сен 18, 01:35    [21664922]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Василий 2
Member

Откуда:
Сообщений: 238
rgreat
Василий 2,
автор
Ну например, использование переменной может произойти до ее высечения в мраморе. Некий модуль может быть иниц-н раньше.
Мы говорим не абстрактную глобальную переменную а про вполне конкретную из System.SysUtils, иннициализируемую в нем же в разделе initialization.

Как она может быть не иннициализированой при ее использовании? ;)

Ты же её предлагал заполнять фиксированными значениями. Это я и имел в виду.
5 сен 18, 14:39    [21665752]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
rgreat
Member

Откуда:
Сообщений: 4481
Василий 2
Ты же её предлагал заполнять фиксированными значениями. Это я и имел в виду.

Я предлагал выставить её 1 раз при старте ПО и больше не трогать.
5 сен 18, 20:00    [21666222]     Ответить | Цитировать Сообщить модератору
 Re: FloatToStr и знак разделителя десятичной дроби в разных системах  [new]
Василий 2
Member

Откуда:
Сообщений: 238
rgreat
Василий 2
Ты же её предлагал заполнять фиксированными значениями. Это я и имел в виду.

Я предлагал выставить её 1 раз при старте ПО и больше не трогать.

Ну. А старт ПО - понятие растяжимое.
6 сен 18, 11:57    [21666730]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / Delphi Ответить