Strtofloat delphi не работает
Мне нужно прочитать текстовый файл, все значения в котором записаны в виде x.yyyy (напр. 6.3245), и преобразовать их в тип Extended для дальнейшей работы с ними. При попытке использовать функцию StrToFloat Delphi вываливается с ошибкой EConvertError.
e:= StrToFloat (‘6.3245’) // Ошибка EConvertError ‘6.3245 is not a valid floating point value’.
При этом, почему–то, строка e:=StrToFloat (‘6,3245’), где вместо разделителя используется не точка, а запятая, ошибки не вызывает. С чем это связано и как можно решить эту проблему?
Семен Сорокин © ( 2004-09-12 14:14 ) [1]
Vulko © ( 2004-09-12 16:50 ) [2]
В win можно задать разделитель дробной и целой частей. По дефолту в русской версии разделителем является запятая.
Vulko © ( 2004-09-12 16:50 ) [3]
QuasiLamo © ( 2004-09-12 18:15 ) [4]
Пусть в строке s хранится число. После этих двух сток
s:=stringreplace(«.»,DecimalSeparator,s,[]);
s:=stringreplace(«,»,DecimalSeparator,s,[]);
какой бы ни был объявлен разделитель в системе, заменится на правильный.
Сам придумал и всегда так делаю. 🙂
> [4] QuasiLamo © (12.09.04 18:15)
Либо так: (с учетом «x.yyyy»)
var
SavDecimalSeparator: Char;
begin
SavDecimalSeparator := DecimalSeparator;
DecimalSeparator := «.»;
try
. работаем с файлом .
finally
DecimalSeparator := SavDecimalSeparator;
end;
end;
Возможно, в данной частной задаче можно и не восстанавливать 😉
PVOzerski © ( 2004-09-13 10:05 ) [6]
Я бы использовал val вместо StrToFloat. Эта процедура всегда считает десятичным разделителем точку.
Mim1 © ( 2004-09-13 10:10 ) [7]
> [5] KSergey © (13.09.04 09:10)
> > [4] QuasiLamo © (12.09.04 18:15)
>
> Либо так: (с учетом «x.yyyy»)
Либо так
raiks ( 2004-09-13 11:17 ) [8]
Всем большое спасибо! Разобрался, все работает.
Источник
Strtofloat delphi не работает
Здорово всем! У меня вопрос такого плана. Никогда с этим не сталкивался и не могу понять где хоть искать. Вот в чем проблема! У меня есть функция преобразования строки в десятичное число, выглядит она следующим образом:
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]
появилась идея где то я читал на тему того, что в зависимости от настроек винды разделителем целой и дробной части может быть . или ,
уже не помню читал или приснилось, но если идей нет то можно проверить эту )
Да это понятно, вот только я и то и то пробовал. Пофигу.
я ( 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.
Я ему верю. да и врать он не умеет
З.Ы.
TryStrToFloat + F1
> я (12.11.11 15:52) [2]
> а понял 🙂
А я вот нет, может расскажешь?
Dennis I. Komarov © ( 2011-11-12 16:08 ) [8]
Inovet © ( 2011-11-12 16:11 ) [9]
> [6] я (12.11.11 16:04)
> функция StrToFloat(S: String): Extended
real устаревший тип. Надо пользоваться: float, double, extended.
> [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 то
> я буду одно делать, а если что-то другое — значит все хорошо!
> Можно работать дальше!!
хозяин — барин, только ректально все это.
> [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]
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]
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]
забыл про вторую форму настолько, что совсем 🙂
Источник