Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Ошибка is not a valid floating point value


Автор: IamDreamer 22.3.2011, 19:07
В Memo1 текст:
Цитата

0,1
0,3
0,25

в Memo2:
Цитата

20
21
21,3

При выполнении кода
Код

procedure TForm1.Button3Click(Sender: TObject);
var Temp, N: Extended;
i: Integer;
U1, U2, I1, I2: Real;
begin
i:=1;
while i<=Memo1.Lines.Count do
  begin
    if (Memo1.Lines.Count-I)=0 then
      begin
        I1:=StrToFloat(Memo1.Lines[i-1]);
        I2:=StrToFloat(Memo1.Lines[i]);
        U1:=StrToFloat(Memo2.Lines[i-1]); // На этой строке
        U2:=StrToFloat(Memo2.Lines[i]);
        Temp:=Abs(1.6*IntPower(10, -19)*Abs(U2-U1)/1.38*IntPower(10, 23)/Ln(I1/I2));
        Memo3.Text:=Memo3.Text+FloatToStr(Temp);
        Memo3.Lines.Add('');
      end
    else
      begin
        I1:=StrToFloat(Memo1.Lines[i]);
        I2:=StrToFloat(Memo1.Lines[i+1]);
        U1:=StrToFloat(Memo2.Lines[i]);
        U2:=StrToFloat(Memo2.Lines[i+1]);
        Temp:=Abs(1.6*IntPower(10, -19)*Abs(U2-U1)/1.38*IntPower(10, 23)/Ln(I1/I2));
        Memo3.Text:=Memo3.Text+FloatToStr(Temp);
        Memo3.Lines.Add('');
        i:=i+2;
      end;
  end;
end;


вылетает ошибка <Project raised exception class EConvertError with message ''' is not a valid floating point value'>. В чём ошибка? 

Автор: northener 22.3.2011, 19:45
Цитата(IamDreamer @  22.3.2011,  19:07 Найти цитируемый пост)
В чём ошибка?

Значит там пустая строка.

Автор: IamDreamer 22.3.2011, 19:56
Цитата(northener @  22.3.2011,  22:45 Найти цитируемый пост)
Значит там пустая строка. 

Видимо, напортачил с индексами... Спасибо.

Автор: THandle 22.3.2011, 20:10
IamDreamer, может на всякий случай еще использовать TryStrToFloat?

Автор: IamDreamer 22.3.2011, 20:18
THandle, вообще можно, но. Первоначально в Memo числа заносятся из текстового файла (по условию решаемой задачи). Реализовано вот так:
Код

procedure TForm1.Button2Click(Sender: TObject);
var F: textfile;
begin
AssignFile(F, OpenDialog1.FileName);
Reset(F);
while not Eof(F) do
    begin
      Readln(F, t, I, U);   // t, i, U - глобальные переменные, которым нужно присвоить значения из файла
      Memo1.Text:=Memo1.Text+FloatToStr(I);
      Memo1.Lines.Add('');
      Memo2.Text:=Memo2.Text+FloatToStr(U);
      Memo2.Lines.Add('');
    end;
CloseFile(F);
end;

Перед началом процедуры нужно указать путь к файлу с данными. Мне бы лучше сделать проверку на существование файла (если, например, путь к файлу не указали, а сразу попытались считать данные). 

Автор: Frees 22.3.2011, 21:00
Цитата(IamDreamer @  22.3.2011,  23:18 Найти цитируемый пост)
Перед началом процедуры нужно указать путь к файлу с данными

Код

FileExists(OpenDialog1.FileName)


и еще  (на всякий случай) в мемо можно сразу грузить файл....
Код

   Memo1.Lines.LoadFromFile(OpenDialog1.FileName);



Автор: IamDreamer 22.3.2011, 21:41
Цитата(Frees @  23.3.2011,  00:00 Найти цитируемый пост)
и еще  (на всякий случай) в мемо можно сразу грузить файл....

Спасибо, попробовал. Кода так становится меньше, но как переписать в Memo1 не всё содержимое файла, а первый (или любой другой) столбец?

Автор: superVad 22.3.2011, 22:14
Возможно, в начале работы программы стоит сделать так:
Код

  DecimalSeparator := ',';

А то вдруг разделитель точка.

Автор: IamDreamer 23.3.2011, 17:48
Цитата(Frees @  23.3.2011,  00:00 Найти цитируемый пост)
FileExists(OpenDialog1.FileName)

Пишу:
Код

if FileExists(OpenDialog1.FileName)=false then
  begin
    MessageDLG('Не выбран файл!', mtWarning, [mbOk], 0);
    halt;
  end;

На что заменить <halt>, чтобы при ошибке программа возвращалась к этапу выбора файла? Метку создать?

Пробовал запускать OpenDialog.Execute (с последующим Reset()), но при считывании значений из файла вылетала ошибка
http://s1.ipicture.ru/

Автор: superVad 23.3.2011, 17:58
Для начала пиши:
Код

if not FileExists(OpenDialog1.FileName) then

как то оно грамотней.
Ну напиши exit попробуй. А лучше весь код покажи - а то не понятно куда надо возвращаться программе.

Автор: IamDreamer 23.3.2011, 18:01
В первоначальном варианте так и было smile.

Автор: superVad 23.3.2011, 18:05
IamDreamer, какой ты быстрый  smile 
Exit попробуй - но возможно я не до конца понял что то.

Автор: IamDreamer 23.3.2011, 18:11
superVad, спасибо! То самое.

Автор: Frees 23.3.2011, 18:46
у TOpenDialog есть опция ofFileMustExist - позволит открыть только существующий файл.

Добавлено через 1 минуту и 12 секунд
http://www.beluch.ru/progr/100comp/8_2.htm

Автор: IamDreamer 23.3.2011, 19:05
Сделал так:
Код

while not Eof(F) do
  Try
      Readln(F, t, I, U);
      Memo1.Text:=Memo1.Text+FloatToStr(I);
      Memo1.Lines.Add('');
      Memo2.Text:=Memo2.Text+FloatToStr(U);
      Memo2.Lines.Add('');
  except MessageDLG('Невозможно считать данные... Выберите другой файл', mtWarning, [mbOk], 0); Exit;
    end;

Автор: Frees 23.3.2011, 19:17
а если исключение вызовет FloatToStr, формат числа например кривой ?
то MessageDLG(...  введет в заблуждение и скроет реальную ошибку!

Автор: IamDreamer 23.3.2011, 19:26
Цитата(Frees @  23.3.2011,  22:17 Найти цитируемый пост)
а если исключение вызовет FloatToStr

Страшно представить smile...

Почему TryStrToFloat есть, а TryFloatToStr нет?

Автор: Frees 23.3.2011, 19:30
Цитата(IamDreamer @  23.3.2011,  22:26 Найти цитируемый пост)
Страшно представить ...Почему TryStrToFloat есть, а TryFloatToStr нет?

я FloatToStr и StrToFloat  перепутал...

FloatToStr - врядли вызовет исключение....

Автор: IamDreamer 23.3.2011, 19:38
Обещали файл только с числами. Я их присваиваю переменным, потом вывожу в Memo.

Автор: northener 24.3.2011, 01:01
Цитата(IamDreamer @  23.3.2011,  19:05 Найти цитируемый пост)
Сделал так:


Цитата(IamDreamer @  23.3.2011,  19:38 Найти цитируемый пост)
Обещали файл только с числами.


Ну раз обещали, то можно и так. Вот только кого назовут стрелочником, если что-то пойдет не так?
Ну и вдогонку. Read/Readln могут и не вызвать исключение. Если не включена соответствующая опция компилятора. По умолчанию она включена.

Автор: IamDreamer 24.3.2011, 10:29
Цитата(northener @  24.3.2011,  04:01 Найти цитируемый пост)
Вот только кого назовут стрелочником, если что-то пойдет не так?

Как-нибудь переживу...

Автор: IamDreamer 24.3.2011, 18:36
Файл оказался несколько иной формы: имеет вид
Цитата

11:17:01    1144    268,42    213    65
11:17:02    1144    268,42    213    65
11:17:03    1144    268,42    213    65
11:17:03    1144    268,42    213    65

Переменной типа TTime можно напрямую из файла командой Readln(filename, T) присвоить значение первого столбца (т.е. чтобы после выполнения Readln(Filename, T) значение T=11:17:01)?

Автор: superVad 24.3.2011, 18:58
Я не уверен но возможно надо в FormCreate такое поставить:
Код

  TimeSeparator := ':';
  ShortTimeFormat := 'hh:nn:ss';


И можно будет использовать функцию StrToTime.

ПС Вероятно я ошибся и надо использовать LongTimeFormat вместо ShortTimeFormat.

В общем поэкспериментируй, попробуй как работает такое:
Код

T=StrToTime('11:17:01');

Автор: IamDreamer 24.3.2011, 19:23
Цитата(superVad @  24.3.2011,  21:58 Найти цитируемый пост)
И можно будет использовать функцию StrToTime.

То есть всё-таки надо будет сначала считать как строку, потом перевести в TTime?

Автор: superVad 24.3.2011, 19:34
Цитата(IamDreamer @  24.3.2011,  18:23 Найти цитируемый пост)
То есть всё-таки надо будет сначала считать как строку, потом перевести в TTime?

А как ты еще из текстового файла хочешь считать?  smile 

Автор: IamDreamer 24.3.2011, 19:54
superVad, числа же сразу считываются. 

Автор: superVad 24.3.2011, 20:13
Цитата(IamDreamer @  24.3.2011,  18:54 Найти цитируемый пост)
superVad, числа же сразу считываются. 

Ну попробуй smile, что мешает?

Автор: IamDreamer 24.3.2011, 20:18
Цитата(superVad @  24.3.2011,  23:13 Найти цитируемый пост)
что мешает? 

Код

Var
t: TTime;
...
 Try
      Readln(F, t);
except MessageDLG('Невозможно считать данные...', mtWarning, [mbOk], 0); Exit;
    end;


Файл F имеет вид, как показано выше.

Выполнение приводит к ошибке 

http://s1.ipicture.ru/

Автор: Frees 24.3.2011, 20:22
TTime - это на самом деле Float а в файле у тебя строка, читай строку и StrToTime используй.

Автор: IamDreamer 24.3.2011, 20:31
Frees, спасибо. Теперь другая загвоздка: в строковую переменную в результате Readln(filename, stroka) присваивается вся строка, т.е. "11:17:01    1144    268,42    213    65". Как сделать так, чтобы в эту переменную записывалось только время без редактирования файла?

Автор: Frees 24.3.2011, 20:48
может так, хотя не уверен..
Код

stroka: array [0..7] of char;
Read(filename, stroka) ;




Автор: superVad 24.3.2011, 21:14
Или:
Код

Read(filename, stroka) ;
stroka := copy(stroka,1,8);

Автор: Frees 24.3.2011, 21:26
Цитата(superVad @  25.3.2011,  00:14 Найти цитируемый пост)
Или:


данные после времени тоже надо из строки stroka брать, Read из файла уже следующую строку данных верноет

Автор: IamDreamer 24.3.2011, 21:32
Readln (Filename, Stroka) без ошибок. Если добавить ещё 2 переменные (Readln(Filename, Stroka, A, B)), вылетает та же ошибка. A, B - переменные типа Real.

Автор: superVad 24.3.2011, 23:40
Цитата(Frees @  24.3.2011,  20:26 Найти цитируемый пост)
данные после времени тоже надо из строки stroka брать, Read из файла уже следующую строку данных верноет

Ну использовать другую переменную smile или вообще:  
Код

  T := StrToTime(copy(stroka,1,8));

Автор: northener 25.3.2011, 02:54
2 superVad.
Ну не хочет автор "распарсивать" строки данного ему файла. Ему хочется использовать процедуру  Read/Readln!
Мне бы тоже хотелось бы этого, если бы я не знал, что "компилер маджик" всё-таки не волшебная палочка.
smile

Автор: IamDreamer 25.3.2011, 08:16
В общем, дело вот в чём. Файл имеет расширение .csv, в блокноте его содержимое выглядит так:
Цитата
11:17:01;1144;268,42;213;65;
11:17:02;1144;268,42;213;65;
11:17:03;1144;268,42;213;65;

Readln() не может считать информацию из-за разделителей ';' (пробовал заменить их на пробелы - всё получилось). Запятые, отделяющие целую часть от дробной, вроде переваривает. 

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

Автор: Frees 25.3.2011, 09:15
Цитата(IamDreamer @  25.3.2011,  11:16 Найти цитируемый пост)
В общем, дело вот в чём. Файл имеет расширение .csv

дак работай с ним как с csv, по средствам TStringList (DelimitedText)

Автор: superVad 25.3.2011, 09:51
Как то так:
Код

var
  tsl_file, tsl_str: TStringList;
  i: Integer;
begin
  tsl_file := TStringList.Create;
  tsl_str := TStringList.Create;
  tsl_file.LoadFromFile('путь к файлу');
  tsl_str.Delimiter := ';';
  for i := 0 to tsl_file.Count -1 do
  begin
    tsl_str.Clear;
    tsl_str.DelimitedText := tsl_file[i];
    //тут работаешь с данными
    //в tsl_str[0] будет время и т.д. до tsl_str[4]
  end;
  FreeAndNil(tsl_str);
  FreeAndNil(tsl_file);
end;

Автор: IamDreamer 29.3.2011, 14:47
Тут задание снова поменяли... Новый вид файла с входными данными:
Цитата
MAR 25 14:14:28.7203    -42.60639
MAR 25 14:14:29.3747    -42.26153
MAR 25 14:14:30.0292    -42.43396
MAR 25 14:14:30.6860    -42.29026
MAR 25 14:14:31.3436    -42.34774


Как учесть то, что последнее значение отделено несколькими пробелами?

Автор: Frees 29.3.2011, 14:54
Цитата(IamDreamer @  29.3.2011,  17:47 Найти цитируемый пост)
 несколькими пробелами?

может это Tab ?

Добавлено через 2 минуты и 59 секунд
пример написанный IamDreamer должен был переварить пробелы

Автор: IamDreamer 29.3.2011, 14:58
Попробовал в качестве Delimiter указать ' ' (один пробел) и проверил результат командой 
Код
ShowMessage(tsl_Values[0] + '***' + tsl_Values[1] + '***' + tsl_Values[2] + '***' + tsl_Values[3]);

Результат:
Цитата
MAR***25***14:14:59.4293***-16.33926

Выходит, количество пробелов ему безразлично smile.

Добавлено через 59 секунд
Цитата(Frees @  29.3.2011,  17:54 Найти цитируемый пост)
пример написанный IamDreamer должен был переварить пробелы 

SuperVad. Да, переварил. За что ему ещё раз спасибо! А то я уже выматерил тех, кто мне это задание выдал.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)