Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Crear matriz (https://www.clubdelphi.com/foros/showthread.php?t=73033)

rebufo 28-03-2011 10:16:54

Crear matriz
 
Hola a todos.
Soy nuevo en esto de la programación con Delphi y quisiera saber cómo puedo hacer para buscar una palabra en un documento de texto y crear una matriz con los datos vinculados a esta palabra.
Me explico. Tengo un documento de texto con este formato:
…..
[REPORT]
Status No
Summary No

[OPTIONS]
Units LPS
Headloss D-W
Specific Gravity 1.0

[COORDENADAS]
;ID Coord X Coord Y
10 20 70
11 30 70
12 50 70
13 70 70
21 30 40

[VERTICES]
;ID Línea Coord X Coord Y
…….
Quisiera que leer el campo [COORDENADAS] y crear una matriz con los datos ID, Coord X y Coord Y en columnas independientes, para posteriormente dibujar unos puntos en pantalla con las coordenadas que se indican.
Un saludo y mil gracias.

newtron 28-03-2011 10:47:55

Hola.

De la manera que estás planteando el asunto te va a resultar un poco complicado extraer la información.

Yo te aconsejaría plantear el fichero de esta forma:

[GRUPOS]
Grupo1=Report
Grupo2=Options
etc

[REPORT]
Parametro1=Status No
Parametro2=
Summary No

[OPTIONS]
Parametro1=
Units LPS
Parametro2=Headloss D-W
Parametro3=Specific Gravity 1.0
etc

de esta manera lo que consigues por un lado es poder leer de una forma sencilla y con un bucle los grupos que vas a tener y dentro de cada grupo los parámetros de cada uno de ellos usando la instrucción ReadString para leer ficheros .ini, si no sabes como hacerlo me lo comentas y te preparo un ejemplo sencillo.

Saludos

rebufo 28-03-2011 11:26:27

Crear Matriz
 
Gracias Newton.
Creo que entiendo lo que comentas pero no sé si se puede aplicar para mi problema.
Del archivo de texto inicial únicamente necesito los datos del campo [coordenadas] y el resto son datos que no necesito para nada.
Además el archivo original puede temer un número de líneas variable, por lo que mi idea es decirle al programa que abra el archivo .txt donde se encuentran toda la información, que busque el campo [coordenadas] (independientemente de la posición en la que se encuentre) y que me cree una matriz (o vectores) con cada una de los subcampos ID linea , Coord X y Coord Y.
Después le daría otra orden para que a partir de los datos de esa matriz me dibujara los puntos con sus coordenadas x e y.
Mil gracias de nuevo y un saludo

ecfisa 28-03-2011 13:50:34

Hola rebufo.

Si el documento siempre respeta el orden que mostras en tu mensaje, podrías armar la matriz de este modo:
Código Delphi [-]
type
  TMatriz = array[1..3, 1..100] of integer;  // 100 o el nro máximo de líneas esperado
  ...

implementation

procedure ObtenerValores(var Matriz: TMatriz; var Tope: Integer);
var
  F: TextFile;
  s: string;
  ts: TStrings;
  fil,col: Integer;
begin
  AssignFile(F,'C:\TU_ARCHIVO.TXT');
  Reset(F);
  while not Eof(F) and (s <> '[COORDENADAS]') do  
    ReadLn(F, s); // saltar irrelevantes
  Readln(F,s);    // saltar línea: ";ID Coord X Coord Y"
  fil:= 1;
  while not Eof(F) and (s <> '[VERTICES]') do // o (s <> '') si hay linea en blanco al fin de la serie
  begin
    Readln(F,s);
    try
     ts:= TStringList.Create;
     ts.Clear;
     ts.Delimiter:= ' ';
     ts.DelimitedText:= s;
     for col:= 0 to ts.Count-1 do
       Matriz[col+1, fil]:= StrToInt(ts[col]);
    finally
     ts.Free;
    end;
    Inc(fil);
  end;
  Tope:= fil -1;
  CloseFile(F);
end;
...

Ejemplo de llamada:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  mt: TMatriz;
  t,i: Integer;
begin
  ObtenerValores(mt, t);
  for i:= 1 to t do
    Memo1.Lines.Add(IntToStr(mt[1,i])+'-'+IntToStr(mt[2,i])+'-'+IntToStr(mt[3,i]));
end;

Un saludo.

newtron 28-03-2011 14:00:36

Ok, te he preparado un ejemplo de como lo puedes hacer

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  Fichero: TextFile;
  Id,X,Y: SmallInt;
  sLinea: String;
  iCoordenadas: array of array of SmallInt;
begin
  AssignFile(Fichero,'D:\Temp\Fichero.txt');
  Reset(Fichero);
  While not Eof(Fichero) do begin
    ReadLn(Fichero,sLinea);
    if sLinea='[COORDENADAS]' then begin
      ReadLn(Fichero,sLinea); // Nos saltamos la linea ;ID Coord X Coord Y
      while true do begin
        ReadLn(Fichero,sLinea);
        try
          Id:=StrToInt(Copy(sLinea,1,2));
          x :=StrToInt(Copy(sLinea,4,2));
          y :=StrToInt(Copy(sLinea,7,2));
          SetLength(iCoordenadas,Length(iCoordenadas)+1,3);
          iCoordenadas[Length(iCoordenadas)-1,0]:=Id;
          iCoordenadas[Length(iCoordenadas)-1,1]:=x;
          iCoordenadas[Length(iCoordenadas)-1,2]:=y;
        except
          // Entiendo que cuando de error han acabado las coordenadas
          break;
        end;
      end;
    end;
    if Length(iCoordenadas)>0 then break; // Entiendo que ya ha cogido las coordenadas y me salgo
  end;
  CloseFile(Fichero);
  // Aquí ya tienes las coordenadas en la matriz iCoordenadas y puedes continuar...

end;

Espero que te sirva.
Saludos

P.D. El amigo ecfisa se me ha adelantado jejejee

ecfisa 28-03-2011 16:39:42

Cita:

Empezado por newtron (Mensaje 394802)
P.D. El amigo ecfisa se me ha adelantado jejejee

Si, pero tu código me gusta mas... ;)

Un saludo.

rebufo 28-03-2011 17:03:36

Si señores
 
Bueno, Bueno no os peleeis, los dos codigos me gustan mucho.
La verdad es que me parece impresionante como funciona este foro. Enhorabuena por la parte que os toca.
Lo que yo llevo "rayandome" dos semanas, me lo habeis solucionado en 2 horas. Ahora me toca a mi seguir rayandome para terminar el programa.
Pena que no estais en A Coruña para invitaros a unas cervecitas.
Mil gracias a los dos.

newtron 28-03-2011 17:50:13

Cita:

Empezado por rebufo (Mensaje 394823)
Pena que no estais en A Coruña para invitaros a unas cervecitas.

naaaaaaaaaa hombreeeeeee.... llama al telebirra y que nos manden unas a ecfisa y otras para mi. :D

rebufo 28-03-2011 19:53:23

Hola de Nuevo
 
Newton
He intentando compilar el programa pero me da problemas cuando se terminan los datos del campo [COORDENADAS].
Es decir, la aplicación lee correctamente toda la matriz pero al llegar al final y encontrarse con ausencia de datos, me da un fallo ya que un ‘ ‘ (espacio en blanco) no es un SmallInt.
¿Cómo podría solucionarlo?
Un saludo

ecfisa 28-03-2011 21:11:21

Hola rebufo.

Es extraño, ya que los errores de conversión en el código de newtron, estan contemplados en el bloque try/except...
Yo lo probé con los datos que enviaste y funciona correctamente. ¿ Alguna variación en el formato del archivo de texto ?

Un saludo.

newtron 29-03-2011 09:18:05

Hola.

Lo que se me ocurre es que al ejecutar el programa desde delphi te de el error EconvertError, esto es porque no lo tienes en la lista "Language exception" del debugger, para añadirlo pica en la casilla de la parte baja a la izquierda de la ventana que pone "Ignore this exception type" y luego picas en "continue", de esta forma lo agregas de forma automática a la lista de errores y no te aparecerá de nuevo.

De todas formas si ejecutas el programa compilado no debe de darte ese mensaje.

Saludos

P.D.: ecfisa y yo seguimos esperando esas birras :D

kdemia 29-03-2011 13:17:03

a ver si te sirve ?

Código Delphi [-]
var
  Form1: TForm1;
  Matriz : Array of Array of Integer;

Código Delphi [-]
procedure TForm1.Procesar ( sArchivo: String );
var
  MiArchivo: TStringList;
  i, j, Index: Integer;
  Texto: String;
begin
  MiArchivo := TStringList.Create;
  MiArchivo.LoadFromFile(sArchivo);
  Index := MiArchivo.IndexOf(';ID Coord X Coord Y');

  for i := 0 to Index do
    MiArchivo.Delete(0);

  Index := MiArchivo.IndexOf('[VERTICES]');

  for i := Index - 1 to MiArchivo.Count - 1 do
    MiArchivo.Delete(Index - 1);

  SetLength(Matriz, 3, MiArchivo.Count);

  for i := 0 to MiArchivo.Count - 1 do
  begin
    Texto:= MiArchivo.Strings[i];
    for j := 0 to 2 do
    begin
      Matriz[j, i] := StrToInt(Copy(Texto, 1, Pos(' ', Texto) - 1));
      Delete(Texto, 1, Pos(Texto, ' ') - 1);
    end;
  end;
  MiArchivo.Free;
end;

Llamada al ejemplo:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  Procesar('C:\MiArchivoDeTexto.txt');
end

disculpa no soy muy bueno con los comentarios.. si no entendes alguna linea me preguntas :)

newtron 29-03-2011 13:23:39

Yo flipo con la cantidad de maneras de las que se puede hacer una cosa :D

kdemia 29-03-2011 13:44:20

Quiza para que tengas mas a mano las dimensiones que te quedo la matriz podrias modificar y en vez de un proceso sea una funcion que devuelva un TPoint..

Código Delphi [-]
function Procesar ( sArchivo : String ) : TPoint;

y antes de la operacion

Código Delphi [-]
...
SetLength(Matriz, 3, MiArchivo.Count);
...

podes agregar un
Código Delphi [-]
Result.X := 3;
Result.Y := MiArchivo.Count;


ahh y hay una parte del codigo que esta mal.. y es esta
Código Delphi [-]
Delete(Texto, 1, Pos(Texto, ' ') - 1);
cambiala por esta otra
Código Delphi [-]
Delete(Texto, 1, Pos(Texto, ' '));
si newtron hay incontables maneras de hacer las cosas XD es buenisimo eso .. :P

rebufo 30-03-2011 11:27:48

Hola de nuevo a todos.
Estoy trabajando con el código de Newton, pero sigo teniendo problemas a la hora de generar la matriz y no sé muy bien porque. He leído todo lo anterior y efectivamente tenía problemas por el error EconvertErro, pero aun así nada.
Añadiendo o modificando parte del formato (en el archivo .txt) de la matriz [COORDENADAS] he comprobado que el programa la lee correctamente ya que se detiene (me salta un mensaje de error al ejecutar) en el punto donde he añadido la modificación (por ejemplo la letra A).
Para detectar mejor los errores, quiero visualizar en pantalla los pasos de creación de la matriz iCoordenadas con algo parecido a esto. (en Matlab es mucho más fácil detectar los fallos ya que únicamente necesitas eliminar un ; al final de cada orden para visualizarla lo que se está ejecutando en pantalla).
Código Delphi [-]
  
{ Imprimir los resultados en un diálogo de mensajes }
   begin
    For i := 0 to (Length(iCoordenadas)-1) do
      for j:= 0 to 3 do           // previamente tendría que definir la variable j 
       ShowMessage('Matriz['+intToStr(i)+','+intToStr(i)+'] = '+intToStr(iCoordenadas[i,j]));
    end.
Otra opción que me planteo es la de llamar a las variables Id, X, Y de manera independiente.
¿Qué me recomendáis?
Mil Gracias de nuevo.

kdemia 30-03-2011 17:30:48

probaste el codigo que te puse?

newtron 30-03-2011 18:56:02

A ver... que yo me entere....

¿Has probado a poner un punto de interrupción en la línea:
CloseFile(Fichero);para ver si te da error antes o después de llegar ahí?


La franja horaria es GMT +2. Ahora son las 01:31:12.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi