PDA

Ver la Versión Completa : Necesito ayuda con el manejo de archivos usando delphi 7


mauser1985
12-07-2008, 18:31:26
Veran, estoy usando Dephi 7 y necesito ayuda con un programita que ando creando, la cuestion es la siguiente: necesito abrir el archivo desde la pc y leerlo por eso no hay problema la cuestion es que en el archivo que debo leer los datos aparecen de manera secuencial es decir aparecen varias lineas que no me interesan, el problema se me presenta porque la idea del programa es que me lea desde ciertos marcadores (en este caso se llaman *jhjjhb y *jbjb), y toda la informacion entre esos marcadores (sin incluir a los mismos) debe ir en un archivo creado desde delphi en un archivo nuevo con una extension especifica :confused:.
Ese procedimiento se repite varias veces a lo largo del archivo, para cada informacion de interes se debera crear un archivo especifico:D.
Si me pudieran ayudar con el codigo fuente de manera que me guie al hacer el proghrma se lo agradeceria mucho.
Si lo desean me puede escribir a mi mail mauricioa85@hotmail.com :cool:

coso
12-07-2008, 19:11:56
Hola, seria algo asi...



void Comenzar()
{
TStringList ls;
int numeroarchivo;
char *nombrearchivo = 'nombre';

ls = TStringList.Crear(nulo);
ls->CargarArchivo(nombrearchivo);

for (unsigned char i;i <= ls.items.Count - 1;i++)
{
if (ls[i] = marcador_inicio)
{
TStringList ls_g = TStringList.Create(nill);

while !(i>ls->items.Count || ls.[++i] = marcardor_fin)
ls_g.Add(ls[i]);

ls_g.GrabaraArchivo(nombre_archivo + astring(numeroarchivo) + ext);
ls_g.Liberar;
numeroarchivo++;
}
}
ls.Liberar;
}

,
mas o menos, escribo de cabeza :rolleyes: saludos y espero que te sirva.

mauser1985
12-07-2008, 22:44:21
Gracias por la molestia pero no termino e entender lo que me respondiste, es decir en la parte visual pienso usar un edit un opendialog y los botones que hagan falta para cargar el archivo grabado en mi pc, no entiendo que variables declarar con el codigo que me diste y que elementos visuales deberia usar..

El rchivo de mi interes es algo asi...

****
****
*****
****
*Inicio
1 25 69,4 87,9
2 4,7 85 745,89
3 65,89 9,7 47,8
4 ......................
.
.
.
.
*fin
.
.
.
Como ya explique anteriormente necesito que la info entre (*iniio y *fin) sea grabada en otro archivo con una extension especifica en la cual vayan los valores port orden de numeros sin contar los primeros.
Gracias

coso
12-07-2008, 22:55:44
elementos visuales en principio ninguno, de variables (importantes aparte del contador) dos stringlist, el nombre del archivo a cargar, el numero de archivo a grabar y un string temporal. Mira, te lo pongo en pseudocodigo



funcion Grabar
{
ls StringList // stringlist donde cargaremos el archivo a analizar
ls_g StringList // stringlist que usaremos para grabar los trozos

ls := TStringList.Create
ls_g := TStringList.Create

ls.LoadFromFile(nombre_de_archivo); // cargamos archivo

i = 0
num_archivo = 0

mientras i menor que ls.Numero_de_lineas haz
si ls[i] = '*inicio' entonces
{
num_archivo = num_archivo + 1
ls_g.Clear
s = ls[i]
mientras (s diferente de '*final') y (i menor que ls.Count) haz
{
ls_g.Add(ls[i]
i = i + 1
s = ls[i]
}
ls_g.SaveToFile(nombre_archivo + inttostr(num_archivo) + '.ext');
}
si no i = i + 1

ls_g.Libera // liberamos los objetos TStringList creados
ls.free //
}

mauser1985
12-07-2008, 23:38:35
Ok Gracias me parece que ese codigo si me ayudara pero aun tengo unos problemas pues soy novato en delphi.
No entiendo la parte de num_de_lineas y nom_archivo??? los declaro como una variable??? use un opendialog para localizar el archivo y sacar su ubicacion y escribir esta ubicacion en un edit.
Gracias

coso
12-07-2008, 23:41:30
num de lineas es el numero de lineas que hay en el stringlist (si miras la ayuda de delphi, buscando TStringList, la propiedad count) y si, num_archivo seria para dar un nombre diferente a cada bloque que grabas. Te recomiendo que repases el codigo y lo entiendas bien. saludos

Caro
13-07-2008, 00:01:44
Hola mauser1985, para la parte del OpenDialog debes utilizar su propiedad FileName en el cual esta toda la ruta de tu archivo que has elegido y luego abrilo en el StringGrid.


var
ls : TStringList; // stringlist donde cargaremos el archivo a analizar
ls_g : TStringList; // stringlist que usaremos para grabar los trozos
FileName : String;
begin
ls := TStringList.Create
ls_g := TStringList.Create
if OpenDialog.Execute then
begin
FileName := OpenDialog.FileName;

ls.LoadFromFile(FileName); // cargamos archivo

.........................
.........................
end;


Saluditos

Caro
13-07-2008, 00:49:56
Hola de nuevo, también lo puedes hacer de esta forma, no lo estoy escribiendo de cabeza pero si de memoria.


var
slFile : TStringList; // stringlist donde cargaremos el archivo a analizar
slFileNuevo : TStringList; // stringlist que usaremos para grabar los trozos
FileName : String;
NumeroFile : Integer;
flgInicio, flgFin : Boolean; //Banderitas que nos serviran para saber cuando tenemos un inicio o fin
begin
slFile := TStringList.Create;
slFileNuevo := TStringList.Create;
if OpenDialog.Execute then
begin
FileName := OpenDialog.FileName;

slFile.LoadFromFile(FileName); // cargamos archivo

flgInicio := False;
flgFin := False;
NumeroFile := 1;

for i:=0 to slFile.Count-1 do
begin
if slFile[i]='*Inicio' then
flgInicio := True;

if (slFile[i]='*Fin' then
flgFin := True;

if (flgInicio=True) and (flgFin=False) then //esto lo puedes simplificar, pero es solo para que se entienda
slFileNuevo.Add(slFile[i+1]); //añadimos en el nuevo

if flgFin=True then //grabamos en el archivo
begin
slFileNuevo.SaveToFile('NombreArchivo'+NumeroFile+'.txt');
flgInicio := False;
flgFin := False;
Inc(NumeroFile);
end;//if
end;//for
.................
.................
end;



Saluditos

mauser1985
13-07-2008, 02:57:43
Hola Caro de verdad que muchas gracias, con ese codigo me ayudare para terminar el programa aunque debo descifrar aun como hacer para que la primera columna de numeros no me aparesca y aun no veo el porque el ultimo marcdor (*final) aun me aparece en el archivo final

coso
13-07-2008, 10:30:21
Hola, siguiendo el codigo de Caro, el ultimo marcador te aparece porque el string que comparas es el slFile[i], mientras que el que añades es slFile[i+1]. Esta solución es buena para evitar incluir el slFile[n] = '*inicio', pero falla en la otra. Una manera de corregirlo seria continuando el loop si se encuentra algun marcador...

....
if slFile[i]='*Inicio' then
begin
flgInicio := True;
continue;
end;

if (slFile[i]='*Fin' then
begin
flgFin := True;
continue;
end;

if (flgInicio=True) and (flgFin=False) then //esto lo puedes simplificar, pero es solo para que se entienda
slFileNuevo.Add(slFile[i]); //añadimos en el nuevo
...

saludos.

coso
13-07-2008, 10:44:29
lo de la primera columna puedes solucionarlo haciendo


if (flgInicio=True) and (flgFin=False) then //esto lo puedes simplificar, pero es solo para que se entienda
slFileNuevo.Add(TrimLeft(StrScan(slFile[i],' '))); //añadimos en el nuevo


si miras la ayuda de delphi, te dira que strscan te devuelve una subcadena desde una cadena a partir de encontrar un carácter (en este caso, ' '). Como incluye el carácter donde se empieza, usamos TrimLeft que elimina los espacios iniciales.

saludos, y a ver si te sirve :D

PD : una curiosidad, ese archivo parece de coordenadas. Para q servirá la aplicación? :?

mauser1985
13-07-2008, 14:27:26
Bueno dejame chequear a ver si el programa me hace lo que espero, la aplicacion tiene el siguiente objetivo; para el uso de un programa de pre y postproceso de simulacion en aplicaciones de problemas cientificos y de ingenieria, bueno pues dicho programa necesita ciertos archivos para cargar la geometria y condiciones de un solido.
Necesito abrir leer datos y apartir de ahi, expulsar diferentes archivos desde un unico archivo que es el output de abaqus..

mauser1985
13-07-2008, 14:38:47
Aja y que caracter debo colocar en ' '??? es que compilo y me dice que hay un error de incompatibilidades entre un sring y PAnsiChar

coso
13-07-2008, 14:56:04
como te dije, pegale un repasillo a la ayuda de delphi de strscan :) saludos

mauser1985
13-07-2008, 21:52:59
Resulta que ya ando probando la interface final pero no se donde me guarda el archivo final y es extraño porque lo pruebo cargando y leyendo otros archivos y siempre me lo guarda en Mis Documentos y esta vez no se si me los lee o no, pienso que quizas es porque los datos son numeros reales, y estoy usando un stringlist pero de verdad que no se; les agradeceria si me ayudaran.

coso
13-07-2008, 22:04:56
los datos son numeros reales, pero estan tratados como texto, por lo que no hay problema de usar un stringlist. En cuanto a la localización del archivo, es probable que no le hayas asignado ninguna ruta ('c:\carpeta\nombrearchivo.txt') , solo el nombre, en el momento de grabarlo (lo mas seguro que este en el mismo directorio que el ejecutable)

mauser1985
13-07-2008, 22:16:14
Sr Coso no se encuentra ni en la carpeta donde esta el ejecutable ni en Mis Documentos como cuando hacia las otras pruebas

coso
13-07-2008, 22:17:46
bueno, y si hace una busqueda del archivo, en que localizacion se encuentra?

mauser1985
13-07-2008, 22:21:20
Tamp'oco Sr Coso, realizo una busqueda con el nombre del archivo en toda la pc y no aparece; es extraño porque pruebo ese mismo codigo con otro archivo y si me graba perfectamente en mis documentos, cuando hago al prueba con el archivo de interes no pasa nada es como si nisiquiera lo leyera

mauser1985
13-07-2008, 22:28:30
Bueno ahora me aparece una excepcion me dice: ESTRinglist error with mesage 'List Index out of bounds (30069)'.... Me parece que el string list no tiene suficientes caracteres para abarcar todo el archivo, me equivoco??

coso
13-07-2008, 22:29:49
no hace falta que me trates de usted :D. probablemente es que no se graba el archivo


....
if slFile[i]='*Inicio' then
begin
flgInicio := True;
continue;
end;

if (slFile[i]='*Fin' then
begin
flgFin := True;
continue;
end;

if (flgInicio=True) and (flgFin=False) then //esto lo puedes simplificar, pero es solo para que se entienda
begin
showmessage('Dentro del bucle...')
slFileNuevo.Add(slFile[i]); //añadimos en el nuevo
end;
...


si, ejecutando el programa, no te aparece este showmessage, es que no se entra. Quiza sea entonces que los marcadores estan incorrectos (ten en cuenta que '*Inicio' es distinto de '*inicio')

coso
13-07-2008, 22:31:37
¿puedes poner el codigo de la funcion?

mauser1985
13-07-2008, 22:38:35
Si ya coloque los marcadores que son correcos y he ahi donde me sale la excecion Sr Coso si quiere le mando el archivo problema y ahi usted vera que es lo que pasa.... pues el codigo que tengo es el mismo que me han sugerido solo con algunas modificaciones

coso
13-07-2008, 22:39:35
no no, ponlo aqui enganchado, en un mensaje, por si a alguien luego le sale el mismo error...

mauser1985
13-07-2008, 22:42:46
ok, este es la excepcion...
Project gid_1.exe raised excepcion class EStringlistError with message 'List Index out of bounds (3006)'. Process stopped. Use step or run to continue...

coso
13-07-2008, 22:44:08
no, la excepcion no, el codigo

mauser1985
13-07-2008, 22:45:26
A ok .

unit gid1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
OpenDialog1: TOpenDialog;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
Button4: TButton;
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
slfile: tstringlist;
slfilenuevo:tstringlist;
filename:string;
Numerofile:integer;
flginicio,flgfin: boolean;
nombre:string;

implementation

{$R *.dfm}

procedure TForm1.Button3Click(Sender: TObject);
begin
Application.Terminate;
end;

procedure TForm1.Button1Click(Sender: TObject);


begin

slfile:=tstringlist.create;
slfilenuevo:=tstringlist.create;

if opendialog1.execute then
begin
filename:=opendialog1.filename;
slfile.loadfromfile(filename);
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
begin
flginicio:=false;
flgfin:= false;
numerofile:=1;
for i:=0 to slfile.count - 1 do
begin
if slfile[i]= '*Node' then
flginicio:=true;
if slfile[i]= '*Element' then
flgfin:=true;
if (flgInicio=True) and (flgFin=False) then
slFileNuevo.Add(slFile[i+1]);
if flgFin=True then
begin

showmessage(' Holaaaaa ');
slFileNuevo.SaveToFile(nombre+'.bas');
flgInicio := False;
flgFin := False;
Inc(NumeroFile);
end;
end;
end;
procedure TForm1.Button4Click(Sender: TObject);


begin
nombre:= edit1.Text;
end;

end.

coso
13-07-2008, 22:59:19
puedes ajuntar tambien el archivo de datos? es secuencial de texto no? yo en principio no le veo ningun fallo (liberar las tstringlist, como mucho)...:confused: (excepto lo comentado antes para no incluir el '*Fin'...) Supongo que pulsaras primero el 1, luego el 4, luego el 2 y finalmente el 3

mauser1985
13-07-2008, 23:02:32
es que el archivo es muy largo si quiere me da su mail y se lo mando por correo, no creo que quepa por aqui de verdad

coso
13-07-2008, 23:03:04
berserker9_94@hotmail.com

coso
13-07-2008, 23:26:47
si, ya se lo que te ocurre. La linea con el marcador de final no es '*Element', es *Element, type=C3D4', por lo que sigue corriendo hasta llegar al final. La excepcion te debe venir probablemente por pasarte de largo en el numero de lineas (en la linea slFileNuevo.Add(slFile[i+1]), probablemente). Otro detalle, el 1 no esta en la primera columna, sino que aparece ' 1, ...'

por lo tanto : deberas canviar el if slFile[i] = '*Element' por if Pos(slFile[i],'*Element') <> 0 y el slFileNuevo.Add( añadir slFileNuevo.Add(Trim(strscan(PChar(TrimLeft(slFile[i]),',')) . Fijate, a más, en los posts anteriores que se comenta sobre el continue.

saludos

mauser1985
13-07-2008, 23:36:01
Sr. Coso modifique todo lo que ud sugirio ya no me sale la excepcion pero el archivo no me lo guarada como antes

coso
13-07-2008, 23:36:55
y lo del hola te sale??

coso
13-07-2008, 23:38:21
perdon, al reves : Pos('*Element',slFile[i]) :) altas horas ya por aqui

mauser1985
13-07-2008, 23:42:19
Buerno disculpe la molestia de verdad que verguenza con usted es que esto ya me tiene de cabeza, le acabo de modificar el pos, y ni me graba el archivo ni me sale el mensaje hola...

begin
flginicio:=false;
flgfin:= false;
numerofile:=1;
for i:=0 to slfile.count - 1 do
begin
if slfile[i]= '*Node' then
flginicio:=true;
continue;
if Pos('*Element, type=C3D4',slFile[i]) <> 0 then
flgfin:=true;
continue;
showmessage(' Holaaaaa ');
if (flgInicio=True) and (flgFin=False) then
slFileNuevo.Add(slFile[i]);

if flgFin=True then
begin
slFileNuevo.Add(Trim(strscan(PChar(TrimLeft(slFile[i])),',')));

slFileNuevo.SaveToFile(nombre+'.bas');
flgInicio := False;
flgFin := False;
Inc(NumeroFile);
end;
end;
end;

coso
13-07-2008, 23:43:35
no, if Pos('*Element',slFile[i]) <> 0...

mauser1985
13-07-2008, 23:45:25
nada no me guarda el archivo

coso
13-07-2008, 23:55:44
procedure TForm1.Button1Click(Sender: TObject);
var
ls,lg : TStringList;
i, n ,r : longint;
nm,ns : string;
begin
if OpenDialog1.Execute then nm := OpenDialog1.Filename else exit; // cogemos nombre a cargar
ls := TStringList.Create; // creamos lista
lg := TStringList.Create; // creamos lista
ls.LoadFromFile(nm); // cargamos fichero
ns := ExtractFilePath(Application.Exename) + '\' + Edit1.Text; // preparamos nombre destino
r := ls.Count; // numero lineas de fichero
i := 0;
n := 0;
while i < r do
if Pos('*Node',ls[i]) <> 0 then // si se encuentra '*Node' en ls[i]...
begin
inc(i); // para saltar la linea con el node
inc(n); // numero archivo
while (Pos('*Element',ls[i]) = 0) and (i < r) do // mientras no se encuentra element y no se ha llegado al final
begin
lg.Add(Trim(strscan(PChar(TrimLeft(ls[i])),','))); // añadimos, eliminando la primera columna
inc(i);
end;
lg.SavetoFile(ns + inttostr(n) + '.txt'); // se ha encontrado element o final, grabamos
end
else inc(i); // si no, seguimos
ls.Free; // liberamos
lg.Free;
end;


es raro, el codigo anterior parecia que no tuviese ningun error. Mañana le echare un vistazo. Este funciona.

mauser1985
14-07-2008, 00:05:02
Muchas gracias Sr Coso ahora con este codigo si me guarda lo que espero

coso
14-07-2008, 00:05:26
if slfile[i]= '*Node' then
begin
flginicio:=true;
continue;
end;
if Pos('*Element',slFile[i]) <> 0 then
begin
flgfin:=true;
continue;
end;

coso
14-07-2008, 00:14:00
nada tranquilo :D para eso estamos (de momento :D)