Strtofloat delphi не работает

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]

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

Читайте также:  Ниссан примера р12 не работает центральный замок с ключа

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

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

← →
я ( 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 то
> я буду одно делать, а если что-то другое — значит все хорошо!
> Можно работать дальше!!

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

Читайте также:  Не работают кнопки руля тойота королла 150

> [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]

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

Источник

Оцените статью