Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 996

/ вопрос решён /

Здравствуйте, уважаемые эксперты и посетители!
Чуть не свихнулся с этой Дельфией на ровном месте. Пишу простенькую прогу. Дошел до ввода float числа. Задаю 1.
В ответ :
Project FltHex.exe raised exception class EConvertError with message "1.' is not a valid floating point value'. Process stopped. Use Step or Run to continue.
Я чуть со стула не рухнул. Задаю : 1.0 1.0Е+00 0.1Е+01 - монофигственно. От огорчения поел пельменей и думаю : пусть сама преобразует туда, потом обратно. И тут все выяснилось. Она почему-то игнорирует американские правила и, как принято у нас, отделяет дробь не точкой, а запятой.
Так возник вопрос: это лечится? В Option не нашел таких настроек. Или это при инсталяции такой режим сделался, и обратно - никак?
Это же никуда не годится - данные будут обрабатываться другими программами, и должен соблюдаться общепринятый стандарт. В Excel при инсталяции, я знаю, такие настройки предусмотрены. Как быть?

Толяныч Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: Толяныч (статус: 4-ый класс)
Вопрос отправлен: 2 февраля 2011, 21:46
Состояние вопроса: решён, ответов: 2.

Ответ #1. Отвечает эксперт: vlsavkin

Здравствуйте, Толяныч!

decimalseparator:='.';

а далее пробуйте, хотя лучше использовать что-то специализированное вроде TMaskedit или обрабатывать допустимость вводимых значений сразу.А еще лучше, сначала взять значение для decimalseparator из настроек локали и затем восстановить его.

Ответ отправил: vlsavkin (статус: 2-ой класс)
Время отправки: 2 февраля 2011, 22:45
Оценка за ответ: 5

Комментарий к оценке: Я уже нашел decimalseparator, только не знал, как к нему обратиться, не думал, что так просто. Thanks !

Ответ #2. Отвечает эксперт: Вадим К

Здравствуйте, Толяныч!
Все очень просто. В Винде есть понятие разделитель дробной части, задается в региональных настройках. Если выбрать страну "США", то будет точка, если выбрать Украину или Россию, то будет запятая. Но не всегда! Абсолютно никто не мешает пользователю зайти и поправить этот разделитель хоть на слеш. И вот тут наступит полный ЧП.
Функция StrToFloat смотрит этот разделитель и преобразовывает в соответствии с ним.
Делать decimalseparator := '.' - это конечно решение, но весьма плохое. В некоторых случаях может вылезти боком (представьте себе, что у пользователя точка выставлена и для разделения тысяч. в этом случае результат например такого StrToFloat(FloatToStr(1000000)) может приятно удивить.

Что же делать? первое - это изучить старую паскальную процедуру val. Она принимает три параметра - первый - строка для преобразования, второй - собственно переменная нужного типа (integer или real), куда нужно записать результат и третья переменная целого типа, куда запишется код ошибки. И у нее разделитель дробной части всегда (!!!) точка. То есть, она преобразовывает числа, записанные в привычном программисту виде.
Эта процедура, в отличии от StrToFloat не генерирует ошибку. Она выставляет код ошибки, который можно проверить.
Если он 0 - все ок, преобразовать удалось. Если же не ноль, значит он указывает на позицию в строке, с которой преобразовать не удалось. Но в этом случае результат преобразования не определен.
Подсмотреть пример можно тут http://www.delphibasics.ru/Val.php

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

Цитата:

Это же никуда не годится - данные будут обрабатываться другими программами, и должен соблюдаться общепринятый стандарт. В Excel при инсталяции, я знаю, такие настройки предусмотрены. Как быть?

Он то как раз и соблюдается:)

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 3 февраля 2011, 10:55
Оценка за ответ: 5

Комментарий к оценке: Спасибо. Уже полегчало :-) За наводку на Basis - отдельное мерси.
А как можно ( и можно ли ) изменить настройку региона ?

Мини-форум вопроса

Всего сообщений: 5; последнее сообщение — 3 февраля 2011, 11:52; участников в обсуждении: 3.
Ерёмин А.А.

Ерёмин А.А. (статус: *Администратор), 3 февраля 2011, 09:31 [#1]:

Толяныч: всё гораздо проще, очень уж приукрасили проблему :-) vlsavkin написал заветную строчку.
bugmenot

bugmenot (статус: 3-ий класс), 3 февраля 2011, 10:24 [#2]:

антизаветную, потому что по "общепринятым стандартам" дробная часть отделяется запятой
виконання програми розпочинається з того самого мiсця, де призупинилося.

Ерёмин А.А.

Ерёмин А.А. (статус: *Администратор), 3 февраля 2011, 10:54 [#3]:

Цитата (bugmenot):

по "общепринятым стандартам" дробная часть отделяется запятой

Стандартам чего? Это и от страны зависит.
bugmenot

bugmenot (статус: 3-ий класс), 3 февраля 2011, 11:27 [#4]:

> от страны
от локали же!
виконання програми розпочинається з того самого мiсця, де призупинилося.

Толяныч

Толяныч (статус: 4-ый класс), 3 февраля 2011, 11:52 [#5]:

У меня уже была мысль ( продуктивная, хоть и малость кривоватая ) в начале работы проги дать ей на преобразование число, запомнить ее separator и далее подменять его на вводе и выводе при необходимости. Но это немножко 'через Альпы'.

3 февраля 2011, 23:51: Статус вопроса изменён на решённый (изменил автор вопроса — Толяныч)

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:42
Выполнено за 0.02 сек.