Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.02.26;
Скачать: CL | DM;

Вниз

StrToFloat()   Найти похожие ветки 

 
a101081 ©   (2011-11-12 15:47) [0]

Здорово всем! У меня вопрос такого плана. Никогда с этим не сталкивался и не могу понять где хоть искать. Вот в чем проблема! У меня есть функция преобразования строки в десятичное число, выглядит она следующим образом:

function StrToFloat2(const S: string):real;
var
i:integer;
begin
if s="" then begin
Result:=-1;
exit;
end;
for I :=1  to  Length(S) do
 begin
 if not (S[I] in ["0".."9",","]) then begin
 Result:=-1;
 exit;
 end;
end;
 Result:=StrToFloat(s);
end;

Все работает (10 компов), но вот на 3-х компьютерах все ровно выдает ошибку плана:

"3,70" is not a valid floating point value.

То есть я уже перевожу строковый формат с запятой...
Вот не могу понять... в чем может быть проблема??? 3,70 - это же типичный REAL... Пробовал менять на точку как разделитель. но тоже самое...
Помогите! Очень надо!!!

Везде системы одинаковые XP (установлены может быть и с разных установочных дисков), но системы Windows XP везде...
Может быть какой библиотеки не хватает???


 
я   (2011-11-12 15:49) [1]

я вот не понял, а зачем тебе эта функция? Есть же уже встроенная.
http://www.delphi-manual.ru/work-with-strings.php?com=yes


 
я   (2011-11-12 15:52) [2]

а понял :-)


 
a101081 ©   (2011-11-12 15:59) [3]

В том то и дело, что функция будет отсекать левые символы которые не 0...9 и запятая... А если что-то попадется то ответом будет -1!!!
Как такое возможно??? На всех компах работает, но вот на 3 не пашет.... из-за чего?


 
я   (2011-11-12 16:01) [4]

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

уже не помню читал или приснилось, но если идей нет то можно проверить эту )


 
a101081 ©   (2011-11-12 16:03) [5]

Да это понятно, вот только я и то и то пробовал... Пофигу...


 
я   (2011-11-12 16:04) [6]

а по выше приведенной ссылке и читал )

В комментариях Андрей предложил поправку в этой функции. Дело в том, что разделитель целой и дробной частей на разных компьютерах может быть и "," и "." - зависит от локальных настроек. Для учёта этого в Delphi существует встроенная константа DecimalSeparator типа Char, принимающая значение символа-разделителя целой и дробной частей. Соответственно, оператор

и еще, между прочим у тебя у внешней функции тип короче, чем у той что приравнивается резалту.  функция StrToFloat(S: String): Extended


 
Dennis I. Komarov ©   (2011-11-12 16:06) [7]


> "3,70" is not a valid floating point value.

Я ему верю... да и врать он не умеет

StrToFloat2("-1")
StrToFloat2("-2")
                        корректно?

З.Ы.
       TryStrToFloat + F1


> я   (12.11.11 15:52) [2]
> а понял :-)

А я вот нет, может расскажешь?


 
Dennis I. Komarov ©   (2011-11-12 16:08) [8]

DecimalSeparator + F1


 
Inovet ©   (2011-11-12 16:11) [9]

> [6] я   (12.11.11 16:04)
> функция StrToFloat(S: String): Extended

real устаревший тип. Надо пользоваться: float, double, extended.


 
Inovet ©   (2011-11-12 16:13) [10]

> [7] Dennis I. Komarov ©   (12.11.11 16:06)
> А я вот нет, может расскажешь?

Ошибку он хочет получить при лидирующих не числовых символах. Только почему ошибка -1 кодируется, и почему не обрабатываются все возможные начальные символы строкового представления числа с плавающей точкой.


 
a101081 ©   (2011-11-12 16:14) [11]

1. Зайдите в ПУСК
2. Выберите "Настройка"
3. Выберите "Панель управления"
4. Выберите "Язык и региональные стандарты"
5. Во вкладке "Региональные параметры" нажмите кнопку "Настройка"
6. В поле "Разделитель целой и дробной части" поставьте "запятую" (,)
7. Нажмите "ОК"

Вот что думается поможет... Только вот пока не проверить... Только завтра буду дома. А так хочется узнать сработает ли???? Может кто-нибудь проверить?
Поменять на точку и запустить функцию... Потом обратно махнуть на запятую...


 
a101081 ©   (2011-11-12 16:17) [12]


> Я ему верю... да и врать он не умеет
>
> StrToFloat2("-1")
> StrToFloat2("-2")
>                         корректно?


дело в том, что у меня не может быть в программе отрицательных!!! 100%!!! Поэтому я и написал такую вот функцию... Мне достаточно. Я потом просто проверю, если возвратит -1 то я буду одно делать, а если что-то другое - значит все хорошо! Можно работать дальше!!


 
Dennis I. Komarov ©   (2011-11-12 16:21) [13]


> В том то и дело, что функция будет отсекать левые символы
> которые не 0...9 и запятая... А если что-то попадется то
> ответом будет -1!!!
> Как такое возможно??? На всех компах работает, но вот на
> 3 не пашет.... из-за чего?

Тогда причем тут некое строковое представление и "floating point value"


 
Dennis I. Komarov ©   (2011-11-12 16:25) [14]


> a101081 ©   (12.11.11 16:14) [11]

За такой подход к стенке и ногами...


> дело в том, что у меня не может быть в программе отрицательных!
> !! 100%!!! Поэтому я и написал такую вот функцию... Мне
> достаточно. Я потом просто проверю, если возвратит -1 то
> я буду одно делать, а если что-то другое - значит все хорошо!
>  Можно работать дальше!!

хозяин - барин, только ректально все это.


 
Inovet ©   (2011-11-12 16:27) [15]

> [11] a101081 ©   (12.11.11 16:14)
> Может кто-нибудь проверить?

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

Если это чтение из файла некоторого оговорённого формата, где разделитель всегда ",", . Пользуйся этой функцией:
function StrToFloat(const S: string; const AFormatSettings: TFormatSettings): Extended;


 
a101081 ©   (2011-11-12 16:30) [16]


> Программа должна с любой локалью работать праввильно, а
> ты уже "," жёстко закодировал.
>
> Если это чтение из файла некоторого оговорённого формата,
>  где разделитель всегда ",", . Пользуйся этой функцией:
> function StrToFloat(const S: string; const AFormatSettings:
>  TFormatSettings): Extended;


В том-то и дело, что перед этой процедурой сначало я меняю все точки на запятые... а уж потом только преобразую строку в число


 
Inovet ©   (2011-11-12 16:32) [17]

> [16] a101081 ©   (12.11.11 16:30)
> В том-то и дело, что перед этой процедурой сначало я меняю
> все точки на запятые...

Вот это и неправильно. А если у пользователя точка разделитель?


 
Dennis I. Komarov ©   (2011-11-12 16:33) [18]


> Inovet ©   (12.11.11 16:13) [10]

Мне было интерестно не Ваше мнение ;)


 
Dennis I. Komarov ©   (2011-11-12 16:35) [19]


> В том-то и дело, что перед этой процедурой сначало я меняю
> все точки на запятые... а уж потом только преобразую строку
> в число

Сказал же, бить будут... Завтра найдется еще один такой умник с "-" разделителем и всем поменяет...


 
a101081 ©   (2011-11-12 16:56) [20]

ну значит напишет о своей проблеме! я отвечу - поменяй там-то...
по умолчанию у всех на винде стоит запятая! а если сам ползал. то поймет, из-за чего!!!


 
Dennis I. Komarov ©   (2011-11-12 17:02) [21]


> по умолчанию у всех на винде стоит запятая! а если сам ползал.
>  то поймет, из-за чего!!!

С чего это? В англицкой по умолчанию точка. И потом это святое право пользователя, поставить себе то, что ему удобно. А твоя святая обязанность, как программиста, сделать так, чтобы работало корректно.
Поэтому [8]


 
Inovet ©   (2011-11-12 17:19) [22]

> [20] a101081 ©   (12.11.11 16:56)
> я отвечу - поменяй там-то...
> по умолчанию у всех на винде стоит запятая!

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


 
Anatoly Podgoretsky ©   (2011-11-12 18:06) [23]

ShowMessage(FloatToStr(3.7))
И результат в студию


 
KilkennyCat ©   (2011-11-12 20:11) [24]


> a101081 ©   (12.11.11 16:14) [11]
>
> 1. Зайдите в ПУСК
> 2. Выберите "Настройка"
> 3. Выберите "Панель управления"
> 4. Выберите "Язык и региональные стандарты"
> 5. Во вкладке "Региональные параметры" нажмите кнопку "Настройка"
> 6. В поле "Разделитель целой и дробной части" поставьте
> "запятую" (,)
> 7. Нажмите "ОК"


я аж проснулся.


 
Inovet ©   (2011-11-12 20:19) [25]

> [24] KilkennyCat ©   (12.11.11 20:11)
> я аж проснулся.

Воремя проснулся? не успел все шаги проделать во сне?


 
KilkennyCat ©   (2011-11-12 21:39) [26]


> Inovet ©   (12.11.11 20:19) [25]

да вроде вовремя... сухо :)


 
avel   (2011-11-14 13:54) [27]

если тебе надо поставить "точный" разделитель, а не определенной средой, то поменяй значение переменной модуля SysUtils DecimalSeparator. "Все ли нормально" обычно проверяют через try except end;


 
Dennis I. Komarov ©   (2011-11-17 01:11) [28]


> то поменяй значение переменной модуля SysUtils DecimalSeparator

Но не забудь при этом сразу вернуть его обратно, ибо это выбор пользователя и он так желает видить этот разделитель :Р


 
Anatoly Podgoretsky ©   (2011-11-17 09:57) [29]


> то поменяй значение переменной модуля SysUtils DecimalSeparator.

Зачем? Чтобы нарушить работу? Стоит ознакомиться по справке, что такое StrToFloat, и уже потом давать дикие советы.


 
OW ©   (2011-11-17 10:26) [30]

function StrToFloat2(const S: string):double;
var
  ec: Integer;
  val: Double;
begin
  if s="" then
  begin
    Result := -1;  // пусто   в
    exit;
  end;
  s := StringReplace(S,".", DecimalSeparator, [frAllReplace]); //заменить возможный разделитель реальным
  s := StringReplace(S,",", DecimalSeparator, [frAllReplace]);
  s := StringReplace(S,"-", DecimalSeparator, [frAllReplace]); //Завтра найдется еще один такой умник с "-" разделителем и всем поменяет...
  TryStrToFloat(S, Val, ec);
  if ec <> 0 then
  begin
    Result := -10; //ошибка конверта
    exit;
  end;
  Result := Val;
end;


 
Dennis I. Komarov ©   (2011-11-17 10:48) [31]


> OW ©   (17.11.11 10:26) [30]

StrToFloat2("1,000,000.01")
И чего? :)))


 
Dennis I. Komarov ©   (2011-11-17 10:52) [32]


> avel   (14.11.11 13:54) [27]
>
> если тебе надо поставить "точный" разделитель, а не определенной
> средой, то поменяй значение переменной модуля SysUtils DecimalSeparator.
>

И получить "is not a valid floating point value." где-нить еще...


 
OW ©   (2011-11-17 11:16) [33]


> Dennis I. Komarov ©   (17.11.11 10:48) [31]
>
>


>  //ошибка конверта


 
Inovet ©   (2011-11-17 11:22) [34]

> [30] OW ©   (17.11.11 10:26)

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


 
OW ©   (2011-11-17 11:44) [35]


> Inovet ©   (17.11.11 11:22) [34]

не понял
вот типичный случай - читать файлы выгрузки с разных машин
где каждая выгружает в своем формате даты/времени
и как?

> достаточно указать нужную в параметре (см выше)

где именно?


 
Anatoly Podgoretsky ©   (2011-11-17 11:46) [36]


> OW ©   (17.11.11 11:44) [35]

Неправильно сделаная программа.
В этим случаях используют системно-независимый формат


 
OW ©   (2011-11-17 11:52) [37]


> Anatoly Podgoretsky ©   (17.11.11 11:46) [36]

согласен вообще то..
это в идеале так должно быть

но а если обяжут использовать что-то собранное на скорую руку кем-то неподумавшим - придется пилить загрузки под . , : -


 
Dennis I. Komarov ©   (2011-11-17 11:58) [38]


> где именно?

function StrToFloat ( FloatString : string ) : Extended;
function StrToFloat ( FloatString : string; const FormatSettings : TFormatSettings ) : Extended;


 
Anatoly Podgoretsky ©   (2011-11-17 12:16) [39]

> OW  (17.11.2011 11:52:37)  [37]

Ну во первых даже и в этом случае формат известен и вторая форма StrToFloat
с ним справится


 
OW ©   (2011-11-17 12:34) [40]

забыл про вторую форму настолько, что совсем :)


 
KilkennyCat ©   (2011-11-17 14:33) [41]


> Dennis I. Komarov ©   (17.11.11 10:48) [31]
>
>
> StrToFloat2("1,000,000.01")

это уже бабло, а не флоат
а для бабла есть currency

function CurrToStrF ( Value : Currency; Format : TFloatFormat; Digits : Integer ) : string;
function CurrToStrF ( Value : Currency; Format : TFloatFormat; Digits : Integer; const FormatSettings : TFormatSettings ) : string;


 
Anatoly Podgoretsky ©   (2011-11-17 14:37) [42]

> KilkennyCat  (17.11.2011 14:33:41)  [41]

Float такой крупный не быват :-)


 
KilkennyCat ©   (2011-11-17 14:53) [43]


> Anatoly Podgoretsky ©   (17.11.11 14:37) [42]

да, и деньги тоже очень редко...


 
Dennis I. Komarov ©   (2011-11-17 15:00) [44]


> это уже бабло, а не флоат

Конечно не флоат, это строка :)
StrToFloat2("1,000,000.0099") так лучше? :)


 
Inovet ©   (2011-11-17 15:09) [45]

> [35] OW ©   (17.11.11 11:44)
> где каждая выгружает в своем формате даты/времени

Значит это третий случай

> [34] Inovet ©   (17.11.11 11:22)
> Если фиг знает что там может быть, то ССЗБ.


 
Inovet ©   (2011-11-17 15:11) [46]

> [35] OW ©   (17.11.11 11:44)
> > достаточно указать нужную в параметре (см выше)
>
> где именно?

> [15] Inovet ©   (12.11.11 16:27)
> Если это чтение из файла некоторого оговорённого формата,
> где разделитель всегда ",", . Пользуйся этой функцией:
> function StrToFloat(const S: string; const AFormatSettings:
> TFormatSettings): Extended;



Страницы: 1 2 вся ветка

Текущий архив: 2012.02.26;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.01 c
15-1320807493
Kerk
2011-11-09 06:58
2012.02.26
Большие сложные GUI


2-1321552371
Laguna
2011-11-17 21:52
2012.02.26
Сообщение компилятра


15-1320870602
Юрий
2011-11-10 00:30
2012.02.26
С днем рождения ! 10 ноября 2011 четверг


15-1320352202
Юрий
2011-11-03 23:30
2012.02.26
С днем рождения ! 4 ноября 2011 пятница


1-1287040846
vasia
2010-10-14 11:20
2012.02.26
SQL запрос с датой в Delphi