![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Здравствуйте! Нужно считать из .dat файла данные (координаты точек). Данные в файле представлены в следующем виде:
2 5 3 3 3 3 7 3 1 10 10 2 95 95 3 10 80 4 10 70 5 40 70 6 40 90 7 35 90 8 35 80 9 15 20 Первую строчку не трогаем, первую строчку считываем в отдельный массив [inf]. Все что ниже первой строчки записываем в массив целых чисел [cities]. Код:
procedure ReadNodes(); begin list:= TStringlist.Create; list.LoadFromFile('c:\nodes.dat'); i:=0; str:= List.Strings[i]; //нулевая строка - информация о препятствиях j:=1; Inf[j]:=Strtoint(Copy(str,j,1)); for i:=1 to NK-1 do begin j:=j+2; inf[i+1]:=Strtoint(Copy(str,j,1)); end; for i := 1 to List.Count - 1 do begin if i>9 then begin str:= List.Strings[i]; from:= Strtoint(Copy(str,1,2)); cities[from].x:=Strtoint(Copy(str,4,2)); cities[from].y:=Strtoint(Copy(str,7,2)); end else begin str:= List.Strings[i]; from:= Strtoint(Copy(str,1,1)); cities[from].x:=Strtoint(Copy(str,3,2)); cities[from].y:=Strtoint(Copy(str,6,2)); end; end; end; Функция не работает, если координаты точки больше 99, то есть координата содержит три цифры. Как это исправить? |
#2
|
||||
|
||||
![]() Не работает потому, что в функции Copy(str,3,2) ты задаешь 2 символа для копирования, и соответственно следующее число начинаешь читать не с той позиции (с 4й например, а не с 5й)
Вот у меня есть ф-ция, которой я превращал строку в вектор, там как разделитель используются запятые, можешь переделать на пробелы Код:
Function ConsoleCommand.texttopoint(var text:string;var Point:Tvector):Boolean; var str1,xstr,ystr,zstr:string;err:integer;len,zap1:integer; temp:Single; begin str1:=text; len:=length(str1); if len>=5 then begin zap1:=pos(',',str1); xstr:=copy(str1,1,zap1-1); val(xstr,temp,err); if err=0 then begin delete(str1,1,zap1); zap1:=pos(',',str1); ystr:=copy(str1,1,zap1-1); val(ystr,temp,err); if err=0 then begin delete(str1,1,zap1); zstr:=str1; val(zstr,temp,err); end; end; if err=0 then begin Point.X:=strtofloat(xstr); Point.Y:=strtofloat(ystr); Point.Z:=strtofloat(zstr); result:=true; end else begin text:=format('_Error:"%s" не является координатами 3D точки',[text]); Result:=false; end; end else begin text:=format('_Error:"%s" не является координатами 3D точки',[text]); Result:=false; end; end; |
#3
|
||||
|
||||
![]() Ну а вот такой вариант устроит?
Код:
program Project1; {$APPTYPE CONSOLE} uses SysUtils, Classes; Var Data, Row: TStringList; R,C: Integer; Matrix: Array of Array of Integer; begin Data := TStringList.Create; Data.LoadFromFile('C:\11\nodes.txt'); Data.Delete(0); SetLength(Matrix, Data.Count); for R := 0 to Data.Count - 1 do begin Row := TStringList.Create; Row.Text := StringReplace(Data.Strings[R],#32,#13,[rfReplaceAll]); SetLength(Matrix[R], Row.Count); for C := 0 to Row.Count - 1 do Matrix[R,C] := StrToIntDef(Row[C], 0); Row.Free; end; Data.Free; for R := 0 to High(Matrix) do begin for C := 0 to High(Matrix[R]) do Write(Matrix[R,C]:3); WriteLn; end; ReadLn; end. Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#4
|
|||
|
|||
![]() Большое спасибо за ответы!
YVitaliy, вы все верно написали, я понимаю, почему не работает, если в координате больше трех цифр, именно это я и хочу преодолеть. Страдалецъ, к сожалению ваш код не запустился. Появляется ошибка в следующей строке: Код:
do Write(Matrix[R,C]:3); Debugger Exception Notification Project Progect1.exe raised an exception class EInOutError with message 'I/O error 105'. Process stopped. Use Step or Run to continue. |
#5
|
||||
|
||||
![]() У вас в качестве разделителя используются пробелы, значит нужно искать его (пробел) в строке с помощью ф-ции Pos, считывать первую координату, задав количеством символов значение етой функции-1, потом удалять из строки символы с 1 до Pos, и повторять так 2 раза для 3х координат, как у меня в примере.
ЗЫ. В данном случае как первая координата идет параметр from, а X и Y как вторая и третья координата так пойдет: Код:
function getcoord(var str:string):string;//функция считывает первую //координату со строки(до первого пробела) а потом удаляет ее вместе с //пробелом var i,j,r:integer; begin result:=str; r:=pos(' ',str);// в кавычках пробел if r=0 then exit; result:=copy(str,1,r-1);//копируем строку до пробела delete(str,1,r);//удаляем символы строки до пробела включительно end; procedure ReadNodes(); begin list:= TStringlist.Create; list.LoadFromFile('c:\nodes.dat'); i:=0; str:= List.Strings[i]; //нулевая строка - информация о препятствиях j:=1; Inf[j]:=Strtoint(Copy(str,j,1)); for i:=1 to NK-1 do begin j:=j+2; inf[i+1]:=Strtoint(Copy(str,j,1)); end; for i := 1 to List.Count - 1 do begin if i>9 then begin str:= List.Strings[i]; from:= Strtoint(getcoord(str)); cities[from].x:=Strtoint(getcoord(str)); cities[from].y:=Strtoint(getcoord(str)); end else begin str:= List.Strings[i]; from:= Strtoint(getcoord(str)); cities[from].x:=Strtoint(getcoord(str)); cities[from].y:=Strtoint(getcoord(str)); end; end; end; Последний раз редактировалось YVitaliy, 16.12.2011 в 16:28. |
#6
|
|||
|
|||
![]() Почему вы считываете символы, а не числа? Можно вот так:
Код:
type TCity = record x, y : Integer; end; TForm1 = class(TForm) Button1: TButton; StringGrid1: TStringGrid; OpenDialog1: TOpenDialog; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } c: array[1..10] of TCity; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var F: TextFile; I, J: Integer; begin if not OpenDialog1.Execute then Exit; AssignFile(F, OpenDialog1.FileName); Reset(F); ReadLn(F); // пропускаем первую строку for I:= 1 to 5 do begin Read(F, J, c[J].x, c[J].y); // считываем числа // просмотр StringGrid1.Cells[1,J]:= IntToStr(c[J].x); StringGrid1.Cells[2,J]:= IntToStr(c[J].y); end; CloseFile(F); end; |
#7
|
||||
|
||||
![]() Тоже неплохой вариант
![]() |
#8
|
||||
|
||||
![]() Не понял, какая нафик ошибка ввода/вывода может быть при выводе на консоль. Бред какой-то. Код абсолютно рабочий для приведенного выше примера данных.
AlexSku если вы будете читать из текстового файла как число, то вы получите бред. В текстовом виде у вас будет 5. А если прочитать этот текст как число, то будет уже 53 Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#9
|
||||
|
||||
![]() Страдалецъ, вы неправы, данная функция рабочая, позволяет считать последовательно записанные значения из строки в файле, единственный ее недостаток - доступна только при работе с файлом, а если есть отдельная строка?
|
#10
|
|||
|
|||
![]() Цитата:
|
#11
|
|||
|
|||
![]() Цитата:
Пример, естественно, приблизительный (напр., чтение надо вести до конца файла - Eof). |
#12
|
||||
|
||||
![]() Да, но есть же класс String, и я думаю, он к файлу отношения не имеет. А данная функция в конечном итоге имхо тоже ищет пробелы для считывания нужных данных
|
#13
|
|||
|
|||
![]() Всем большое спасибо за помощь, особенно YVitaliy! Все заработало, буду теперь разбираться как!
![]() |