![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | 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! Все заработало, буду теперь разбираться как!
![]() |