Decimal separator delphi/lazarus
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Decimal separator delphi/lazarus

Decimal separator delphi/lazarus

Ответ
Поиск в этой теме
Непрочитано 05.09.2013, 09:04 #1
Decimal separator delphi/lazarus
ETCartman
 
Регистрация: 09.12.2008
Сообщений: 4,643

вопрос по сабжу к знающим людям. куда прописать переменную (в программе несколько юнитов и форм) чтобы сразу везде отпала проблема с десятичным разделителем? Возможно это нужно сделать при загрузке. Просто я мало знаком с делфи, методом тыка иногда приходится что то делать. вроде бы это переменная.
Просмотров: 7697
 
Непрочитано 05.09.2013, 09:48
#2
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от ETCartman Посмотреть сообщение
Просто я мало знаком с делфи, методом тыка иногда приходится что то делать.
И что, это адекватная причина не задавать свой вопрос на специализированных форумах "delphi/lazarus"? Хотя, если тебе "шашечки", а не "ехать", то можно и здесь...
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Непрочитано 05.09.2013, 15:39
#3
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


программисты делают так: создают класс на основе текстбокса, компилируют в пакет, устанавливают в IDE, пользуются.
gomer вне форума  
 
Непрочитано 05.09.2013, 19:37
#4
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,352
<phrase 1=


Перед выполнением операций по преобразованию строк поставить
Код:
[Выделить все]
DecimalSeparator:='.';
>>куда прописать переменную (в программе несколько юнитов и форм) чтобы сразу везде отпала проблема с десятичным разделителем?
таких мест много
zamtmn вне форума  
 
Непрочитано 05.09.2013, 19:42
#5
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


вообще, чтобы не изобретать подобного рода велосипеды, давно существует такое понятие, как "локализация".
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Непрочитано 05.09.2013, 20:29
#6
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Не надо никаких классов. Просто где-то в свой библиотечный модуль (в котором в uses включить SysUtils) включить функции:

Код:
[Выделить все]
function FloatToStrUS(value: double; decimals: integer): string;
var
  Oldseparator: char;
begin
  Oldseparator := DecimalSeparator;
  DecimalSeparator := '.';
  Result := FloatToStrF(value, ffFixed, 3, decimals);
  DecimalSeparator := OldSeparator;
end;

function StrUStoFloat(value: string): double;
var
  Oldseperator: char;
begin
  Result := 0;
  Oldseparator := DecimalSeparator;
  DecimalSeparator := '.';
  try
    Result := StrToFloat(value);
  except
  end;
  DecimalSeparator := OldSeparator;
end;
Применять там, где надо читать-писать числа в файл, например. Можно сделать аналогичные с разделителем ','. Такой прием должен обязательно использоваться, чтобы программа была независимой от настроек Windows.
ShaggyDoc вне форума  
 
Непрочитано 05.09.2013, 21:43
#7
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Эт все каменный век
gomer вне форума  
 
Автор темы   Непрочитано 06.09.2013, 07:58
#8
ETCartman


 
Регистрация: 09.12.2008
Сообщений: 4,643


спасибо всем за ответы. Метод ShaggyDoc мне понятен и близок, но программа частично писана не мной, где она там читает и пишет - даже сложно сообразить, во множестве мест. Боюсь что поиском заменой я только запорчу все.
У меня вопрос к вам, zamtmn, про
DecimalSeparator:='.';
и про то что таких мест много. Я на самом деле не знаю просто в каком месте в юните нужно вставлять эту строчку - после какого ключевого слова. Там где глобальные переменные декларируются? Ну то есть я совсем темный человек в делфи. А любимым методом тыка есть вероятность накосячить а не исправить
ETCartman вне форума  
 
Непрочитано 06.09.2013, 09:40
#9
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


DecimalSeparator - это "глобальная переменная", описанная в модуле SysUtils. Он обычно включается в каждый другой модуль - там все основные процедуры и функции Pascal. Когда используются штатные функции, например StrToFloat, внутри них происходит чтение текущего состояния DecimalSeparator.

Цитата:
даже сложно сообразить, во множестве мест. Боюсь что поиском заменой я только запорчу все.
И соображать особенно не надо - искать, например, вызовы StrToFloat. Но заменять не автоматически, а посмотрев, как применяется. Менять надо там, где возможен пользовательский ввод или чтение из файла. Причем ввод через правильные контролы обычно учитывает текущую настройку Windows. Там просто не дают ввести точку вместо запятой или наоборот.

Альтернатива - написать, что для этой программы делать такую-то настройку Windows, что сразу делает программу любительской.
ShaggyDoc вне форума  
 
Непрочитано 06.09.2013, 10:44
#10
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,352
<phrase 1=


ETCartman
Если нет желания разбираться что там и как в чужой программе - попробуй просто добавить в секцию инициализации соответствующего юнита (перед последним end. с точкой или после ключевого слова initialization если оно есть в конце модуля). Также можно добавить в "основной" файл проекта перед application.run.
Но лучше таки разобраться и "обрамить" только нужные места.
Делать "обертки" над системными функциями преобразования имхо не выход - таких функций довольно много, не только StrToFloat, придется править чужой код, "лишние" действия какими бы мизерными они небыли скажутся на производительности при обработке больших входных данных
zamtmn вне форума  
 
Автор темы   Непрочитано 09.09.2013, 10:50
#11
ETCartman


 
Регистрация: 09.12.2008
Сообщений: 4,643


спасибо! работает после ключевого слова initialization
- в основном модуле
ETCartman вне форума  
 
Непрочитано 09.09.2013, 11:08
#12
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Цитата:
Сообщение от ETCartman Посмотреть сообщение
спасибо! работает после ключевого слова initialization
- в основном модуле
Так вообще незачем делать. Просто в "основной модуль" в uses включаются любые другие модули. Тогда в основном модуле становятся доступными функции и процедуры, описанные во включаемых модулях. Чтобы они были доступны, надо описания функций включать в секцию interface, а реализацию - в секцию implementation.
Например:

Код:
[Выделить все]
unit StringsUtils;

interface

function FloatToStrUS(value: double; decimals: integer): string;
function StrUStoFloat(value: string): double;

implementation
uses SysUtils;

function FloatToStrUS(value: double; decimals: integer): string;
var
  Oldseparator: char;
begin
  Oldseparator := DecimalSeparator;
  DecimalSeparator := '.';
  Result := FloatToStrF(value, ffFixed, 3, decimals);
  DecimalSeparator := OldSeparator;
end;

function StrUStoFloat(value: string): double;
var
  Oldseperator: char;
begin
  Result := 0;
  Oldseparator := DecimalSeparator;
  DecimalSeparator := '.';
  try
    Result := StrToFloat(value);
  except
  end;
  DecimalSeparator := OldSeparator;
end;
end.
А в initialization включаются, при необходимости, действия, которые необходимо выполнить при загрузке программы. Это своего рода "autoexec". В подавляющем большинстве случаев этого не надо делать, хотя иногда не обойтись. Можно, конечно там записать и изменение DecimalSeparator, но это в итоге плохо кончится.
ShaggyDoc вне форума  
 
Непрочитано 09.09.2013, 13:23
#13
bahil


 
Сообщений: n/a


Шёл бы ты отсюда http://www.delphimaster.ru
Есть такая глобальная переменная FormatSeting. Там твой сепаратор и сидит.

Последний раз редактировалось bahil, 09.09.2013 в 13:28.
 
 
Автор темы   Непрочитано 09.09.2013, 17:47
#14
ETCartman


 
Регистрация: 09.12.2008
Сообщений: 4,643


ShaggyDoc
Да спасибо вам за совет. в данном случае проблема в том что код я плохо знаю но знаю что там много чего читает, пишет и так далее. Тестировать каждую функцию сложно (ранее было оттестировано для US опций)
Если я что то заново начну писать на паскале - начну прямо с вашего совета.

Цитата:
Можно, конечно там записать и изменение DecimalSeparator, но это в итоге плохо кончится.
какие могут быть неприятные последствия? то что пользователь будет вводить запятую вместо точки и это приведет к ошибке взаимодействия с программой?

bahil вам тоже спасибо за линк. Но я не пойду куда вы посылаете. Тут на форуме достаточно людей неплохо владеющих вопросом.
На спецфоруме меня пошлют в Faq, потом еще поглумятся, и потом может быть что то выдавят. Тут люди предметные и без понтов - меня больше устраивает
ETCartman вне форума  
 
Непрочитано 09.09.2013, 20:25
#15
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Цитата:
какие могут быть неприятные последствия?
То, что одна из программ изменит глобальные настройки Windows. При этом у пользователя может быть открыто и другое приложение, в котором он привык к другому разделителю. Например вдруг окажется что в Excel числовые ячейки будут восприниматься как строковые.

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

Если уж записывать в initialization, то непременно надо сделать обратное действие в finalization этого же модуля. В этом случае настройки будут устанавливаться при загрузке вашей программы и востанавливаться при её выгрузке.
ShaggyDoc вне форума  
 
Непрочитано 09.09.2013, 21:00
#16
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,352
<phrase 1=


ShaggyDoc, ETCartman
DecimalSeparator к настройкам ОС не имеет никакого отношения и работает только внутри данного сеанса данного приложения. Если его не вернуть обратно, максимум что может произойти - проблемы в других частях программы, которые ожидают запятую, а не точку. Если таких частей нет - то никаких проблем быть не может и восстанавливать ничего ненадо
zamtmn вне форума  
 
Непрочитано 09.10.2013, 02:13
#17
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Вот так просто можно запретить ввод ненужных символов в текстовое поле
Код:
[Выделить все]
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char);
var chars : set of char;
begin
  chars := ['0' .. '9', #8];
  with Sender as TEdit do
  begin
    if Length(Text) = 0 then
      chars := chars + ['-'];
    if Pos(DecimalSeparator, Text) = 0 then
      chars := chars + [DecimalSeparator];
  end;
 
  if not (Key in chars) then Key := #0;
end;
gomer вне форума  
 
Непрочитано 09.10.2013, 10:17
#18
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,352
<phrase 1=


а клипбоард? а числа с е? ненадо ничего запрещать, надо проверять на валидность при нажатии ентера.
но если уже невтерпеж запретить - в лазаре есть стандартные едиты для интов и флоатов, в делфи думаю тоже
zamtmn вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Decimal separator delphi/lazarus



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как извлечь цифры из числа?(на языке C#) Георгий511 Программирование 3 15.12.2012 22:37
ЛИСП слои цвета преобразование Gotch LISP 97 08.11.2011 10:22
Добавление символов в шрифт Александер Программирование 188 01.06.2010 13:30
RGB_color в OLE_color как это сделать? mmax Программирование 25 21.09.2006 10:42
Ед. измерения самостоятельно перескакивают с Decimal на Arch Grinzaid AutoCAD 2 29.10.2003 15:25