Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Funcion para extraer texto de archivos de texto (https://www.clubdelphi.com/foros/showthread.php?t=87764)

JuanOrtega 22-02-2015 18:41:34

Funcion para extraer texto de archivos de texto
 
Hola tengo el siguiente codigo :

Código Delphi [-]

function read_file(const FileName: String): AnsiString;
var
  Stream: TFileStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead);
  try
    SetLength(Result, Stream.Size);
    Stream.ReadBuffer(Pointer(Result)^, Stream.Size);
  finally
    Stream.Free;
  end;
end;

function cortar(archivo: String; deaca: String; hastaaca: String): String;
var text:string;
begin
  text := read_file(archivo);
  Delete(text, 1, AnsiPos(deaca, text) + Length(deaca) - 1);
  SetLength(text, AnsiPos(hastaaca, text) - 1);
  Result := text;
end;

function cut(archivo,Delimit1, Delimit2 :String) :String;
var
  Buffer      :AnsiString;
  ResLength   :Integer;
  i           :Integer;
  PosDelimit  :Integer;
begin
  Buffer := read_file(archivo);
  if Pos(Delimit1, Buffer) > Pos(Delimit2, Buffer) then
    PosDelimit := Length(Buffer)-(Pos(Delimit1, Buffer)+Length(Delimit1))
  else PosDelimit := Length(Buffer)-(Pos(Delimit2, Buffer)+Length(Delimit2));
  Buffer := Copy(Buffer, (Length(Buffer)-PosDelimit), Length(Buffer));
  ResLength := Pos(Delimit2, Buffer)-(Pos(Delimit1, Buffer)+Length(Delimit1));
  for i := 0 to (Reslength-1) do
    Result := Result+Buffer[Pos(Delimit1, Buffer)+(Length(Delimit1)+i)];
end;

Estoy tratando de mejorar mi funcion cortar() para que se parezca mas a la funcion cut() del codigo mostrado , lo que hacen es leer un archivo cualquiera y buscar en ellos texto que este entre dos etiquetas , el problema es que mi funcion cortar() me parece perfecta pero nunca obtengo el mismo resultado que la funcion cut() que parece mas compleja y no entiendo cual es el diferencia entre las dos porque cuando uso texto normal en un string las dos funciones son iguales pero cuando leo un archivo la funcion cut() es notablemente superior.

¿ como mejoro mi funcion cortar() para que haga lo mismo que cut() en los archivos ?

duilioisola 23-02-2015 10:40:49

Cita:

la función cut() es notablemente superior
¿Qué quiere decir esto? Que es más rápida?

Cita:

¿ como mejoro mi función cortar() para que haga lo mismo que cut() en los archivos ?
¿Qué es lo que hace cut() que no hace cortar()?

JuanOrtega 23-02-2015 14:29:52

La funcion cortar() y la funcion cut() hacen lo mismo buscar texto entre dos etiquetas en cualquier archivo ya sea de texto , el problema es que la funcion cut() lo encuentra todo por alguna razon que no entiendo porque la funcion cortar() a veces falla , por ejemplo busco el texto largo que esta entre etiquetas ej [hola]hola mundo[hola] y te devuelve hola mundo , eso pasa tambien en los archivos pero mi funcion cortar() a veces falla y la funcion cut() lo encuentra todo , espero haberme explicado.

duilioisola 23-02-2015 15:50:07

Quizás es porque el fichero tiene caracteres raros en medio.
Puede que el fichero esté formado por caracteres Unicode de mas de un byte y por eso.

Ten en cuenta que read_file devuelve un tipo de dato AnsiString y tu lo cargas dentro de un string.
Dependiendo de la versión del Delphi, un string puede estar formado por caracteres de mas de un byte. El AnsiString solo contempla caracteres de un byte.
Código Delphi [-]
function read_file(const FileName: String): AnsiString;
...

function cortar(archivo: String; deaca: String; hastaaca: String): String;
var text:string;
begin
  text := read_file(archivo);

Si te fijas sobre el final de cut(), verás que hace una transformación de AnsiString a string;

Código Delphi [-]
  // Recorre un AnsiString carácter a carácter y lo concatena a un string.
  // AnsiString son caracteres de un byte.
  // string puede contener caracteres de mas de un byte
  for i := 0 to (Reslength-1) do
    Result := Result+Buffer[Pos(Delimit1, Buffer)+(Length(Delimit1)+i)];

JuanOrtega 23-02-2015 16:27:22

Hola , gracias por la ayuda , parece que el problema es cuando lee archivos binarios con la funcion cortar() por eso no encuentra nada a pesar de que la funcion cut() si lo hace , estuve tratando de mejorar el codigo como hiciste pero me quedo esto :

Código Delphi [-]
function cortar(ruta, delimitador1, delimitador2: string): string;
var
  code: string;
  rta: string;
begin
  code := read_file(ruta);

  Delete(code, 1, AnsiPos(delimitador1, code) + Length(delimitador1) - 1);
  SetLength(code, AnsiPos(delimitador2, code) - 1);
  rta := code;

  if rta = '' then
  begin
    Result := 'Error';
  end
  else
  begin
    Result := rta;
  end;
end;

Probe cambiando los AnsiPos por Pos pero el programa se tilda completamente , tambien intente hacer la conversion que me recomendaste pero no se como relacionar ResLength con mi codigo.

¿ que tendria que hacer ?

engranaje 24-02-2015 12:08:23

Habría que comprobar con los mismos ficheros que tú para estar seguro pero por probar he preparado algo asi en una unit y da la sensación de funcionar como se espera.

Código Delphi [-]
function LeeFichero(const fichero: String): AnsiString;
var
  F: file;
  cuantos: Integer;
  Buf: array[1..1024] of Char;
begin
  result := '';
  AssignFile(F, fichero);
  Reset(F, 1);

  repeat
    BlockRead(F, Buf, SizeOf(Buf), cuantos);
      result := result + Buf;
  until (cuantos = 0);

  CloseFile(F);
end;

function cortar(ruta, delimitador1, delimitador2: string): Ansistring;
begin
  result := LeeFichero(ruta);
  Delete(result, 1, AnsiPos(delimitador1, result) + Length(delimitador1) - 1);
  SetLength(result, AnsiPos(delimitador2, result) - 1);

  if result = '' then
    Result := 'Error';
end;


La franja horaria es GMT +2. Ahora son las 15:33:11.

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