|
Вопрос # 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 (статус: 3-ий класс), 3 февраля 2011, 10:24 [#2]:
антизаветную, потому что по "общепринятым стандартам" дробная часть отделяется запятой
виконання програми розпочинається з того самого мiсця, де призупинилося.
|
|
Ерёмин А.А. (статус: *Администратор), 3 февраля 2011, 10:54 [#3]:
Цитата (bugmenot):
по "общепринятым стандартам" дробная часть отделяется запятой
Стандартам чего? Это и от страны зависит.
|
|
bugmenot (статус: 3-ий класс), 3 февраля 2011, 11:27 [#4]:
> от страны
от локали же!
виконання програми розпочинається з того самого мiсця, де призупинилося.
|
|
Толяныч (статус: 4-ый класс), 3 февраля 2011, 11:52 [#5]:
У меня уже была мысль ( продуктивная, хоть и малость кривоватая ) в начале работы проги дать ей на преобразование число, запомнить ее separator и далее подменять его на вводе и выводе при необходимости. Но это немножко 'через Альпы'.
|
3 февраля 2011, 23:51: Статус вопроса изменён на решённый (изменил автор вопроса — Толяныч)
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|