Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Fin de archivo leyendo archivos de texto (https://www.clubdelphi.com/foros/showthread.php?t=85516)

lbidi 27-03-2014 16:20:40

Fin de archivo leyendo archivos de texto
 
Estimados todos.

Hace dias que vengo con un problema y no puedo darme cuenta donde esta y supongo que 4 ojos ;) veran mucho mas que yo.

Resulta que tengo que leer y procesar varios archivos de texto que se generan automaticamente y son enviados desde equipos medicos hacia una carpeta compartida. Mi sistema los lee e inserta los resultados en el sistema.

Estos archivos pueden contener 1, 2 o n lineas con un formato especifico pero con contenido muy diferente segun el equipo que los envia.

Mi problema resulta al leer el contenido de los archivos segun el siguiente codigo.

Código Delphi [-]
AssignFile( cArchi, cArchivo );
Reset( cArchi );
while not Eof( cArchi ) do
begin
    Readln( cArchi , cCadena );

    nficha := StrToInt(Trim( Copy( cCadena, 1, 6 ) ) )

    while ( not Eof( cArchi ) ) and ( nficha = StrToInt(Trim( Copy( cCadena, 1, 6 ) ) ) ) do
    begin
//    ... Proceso datos en cadena....
         Readln( cArchi , cCadena );
    end

end

Necesito hacer ese corte de control en el medio porque puedo tener varias lineas para el mismo paciente, el problema real que tengo es que cuando ejecuta el comando READLN, y x ej. el contenido es solo una linea, al entrar al segundo while y pregunta por eof(), ya llego al final, entonces no me procesa nada, lo mismo cuando entro en el segundo while cuando contiene mas de una linea, al leer la ultima linea del archivo, tambien eof() resulta true y por eso no me la procesa.

La verdad hace dias que estoy tratando de resolver esto y siempre me pierde la ultima linea.
Hay otra manera de usar readln() u otra funcion que me devuelva fin de archivo cuando intengo seguir?

Gracias mil a quien pueda responder.

Saludos

Leo

duilioisola 27-03-2014 17:37:44

¿Conoces la sentencia repeat..until?
Código Delphi [-]
AssignFile( cArchi, cArchivo );
Reset( cArchi );

// Si no está vacío empiezo a procesarlo
if (not EOF(cArchi) then
begin
   // Repito este bloque hasta que encuentro la condición de salida
   repeat
      // Leo linea
      Readln(cArchi, cCadena);
      // ... Proceso datos de la cadena
      [...]
   until EOF(Archi) or  (nficha = StrToInt(Trim(Copy(cCadena, 1, 6)))
end;

lbidi 28-03-2014 14:25:13

Hola duilioisola, gracias por responder.
Si la conocia, y antes de postear la pregunta, tambien la habia probado y no me conformaba.

Igual lo pude solucionar cargardo el archivo de texto en un stringlist y procesando todas las lineas
del mismo.

Muchas gracias.

Saludos

ecfisa 28-03-2014 20:16:45

Hola Ibidi.

Sólo como comentario, se puede efectuar con ambas estructuras de repetición. Por ejemplo, los siguientes códigos son equivalentes:
Código Delphi [-]
procedure MostrarConWhile(aFileName: TFileName; nFicha: Integer; LB: TListBox);
var
  F: TextFile;
  Cadena: string;
begin
  AssignFile(F, aFileName);
  try
    Reset(F);
  except
    raise Exception.Create('Archivo no encontrado');
  end;
  Readln(F, Cadena);
  while not Eof(F) and (nFicha = StrToInt(Trim(Copy(Cadena,1,6)))) do
  begin
    LB.Items.Add(Cadena); // Ejecutar acción (condición ya validada)
    Readln(F, Cadena);
  end;
  CloseFile(F);
end;

Código Delphi [-]
procedure MostrarConRepeat(aFileName: TFileName; nFicha: Integer; LB: TListBox);
var
  F: TextFile;
  Cadena: string;
begin
  AssignFile(F, aFileName);
  try
    Reset(F);
  except
    raise Exception.Create('Archivo no encontrado');
  end;
  repeat
    Readln(F, Cadena);
    if nFicha = StrToInt(Trim(Copy(Cadena,1,6))) then // Validar condición
      LB.Items.Add(Cadena);  // Acción
  until Eof(F) or (StrToInt(Trim(Copy(Cadena,1,6))) <> nFicha);
end;
La diferencia es que en el ciclo while se comprueba la condición al ingresar, de allí que sea necesaria la lectura previa.
Con repeat es innecesaria la lectura previa, pero hay que verificar la condición antes de ejecutar la acción, de otro modo la ejecutaría al menos una vez. Lo mismo sucedería al leer el elemento posterior al último que satisfizo la condición.

De todos modos, creo que la solución mas simple es la que usaste (TStringList).

Saludos :)


La franja horaria es GMT +2. Ahora son las 15:40: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