Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-06-2006
jonmendi jonmendi is offline
Miembro
 
Registrado: dic 2004
Posts: 110
Poder: 20
jonmendi Va por buen camino
file of, caracter de separación

hola a todos!
No se si es el lugar más adecuado, ya que ahora estoy programando en Pascal, pero supongo que muchos de vosotros habréis hecho pinitos (y más) con él.
Estoy haciendo un programilla que debe guardar unos registros de un tipo determinado (tipoNuevo) en un fichero en disco. Creo un file of tipoNuevo, y al grabar o leer los registros me los graba / lee bien. El problema surge cuando edito el archivo como texto. Entre campo y campo de cada registro veo que me ha insertado un carácter variable (puede ser cualquiera). El asunto es que necesito quitar este caracter, pues las ristras que le dejo yo las usa otro programa que no espera encontrar nada ahí.
He probado a escribir todo como un archivo de texto, pero el problema es que al permitir solo reset, rewrite, append no puedo acceder a la fila que yo quiero y modificarla.
¿Alguien me puede dar laguna pista?
Muuuuuuuuuuchísimas gracias.
Jon
Responder Con Cita
  #2  
Antiguo 07-06-2006
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Como archivo de texto, si usas Rewrite te borrará el archivo, pero con Reset te puedes situar la principio, y despues con ReadLn puedes ir leyendo hasta situarte en la línea adecuada, para modificar, usas WriteLn.

Si usas un File of TRecord, no puedes modificar despues a mano el archivo, porque se crean las marcas de fin de registro, si lo modificas, despues al leer dará fallos.

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #3  
Antiguo 07-06-2006
jonmendi jonmendi is offline
Miembro
 
Registrado: dic 2004
Posts: 110
Poder: 20
jonmendi Va por buen camino
gracias Lepe,
es lo que he intentado, pero existe el siguiente problema. Si abro con reset el archivo es solo de lectura (ya que es de texto), por lo que aunque lea las líneas y me posiciones en la que yo quiero, a la hora de escribir tendré que hacer un rewrite, con lo que me borrará el archivo y me creará uno vacío.
¿Alguna ideas más?

Muchas gracias,
Jon
Responder Con Cita
  #4  
Antiguo 07-06-2006
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Quizás fuera conveniente leer todo el archivo en memoria ¿es muy grande?

Si no lo es, 2000 o 3000 registros, puedes usar un TStringList y quitarte de todos esos problemas:

Código Delphi [-]
var Archivo:TStringList;
begin
  Archivo := TStringList.Create;
  Archivo.LoadFromFile('c:\mio.txt');
  if Archivo.Count > 129 then // si tiene más de 129 líneas
    Archivo[128] := 'Por la cara modifico el texto';
  if Archivo.Count > 0 then
    Archivo[0] := Archivo[0] + ' Añado texto a la primera fila';

  if Archivo.Count > 3 then
    Archivo.Insert(2,'inserto en la posición 3, recuerda empieza en cero');
  Archivo.Add('añado al final este texto');
  Archivo.Delete(0); // borro la primera linea
  Archivo.SaveToFile('c:\mio.txt');
  FreeAndNil(Archivo);
end;

saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #5  
Antiguo 07-06-2006
jonmendi jonmendi is offline
Miembro
 
Registrado: dic 2004
Posts: 110
Poder: 20
jonmendi Va por buen camino
muchas gracias lepe, pero (parezco el hombre de los peros) me temo que en turbo pascal no existe TStringList (o al menos yo no lo conozco). Lo único que se me ocurre es antes de escribir leer todo, añadir en el sitio adecuado la ristra que quiero y volver a escribir todo. Pero no me convence en absoluto.

Un saludo
Jon
Responder Con Cita
  #6  
Antiguo 07-06-2006
luisgutierrezb luisgutierrezb is offline
Miembro
 
Registrado: oct 2005
Ubicación: México
Posts: 925
Poder: 19
luisgutierrezb Va por buen camino
porque no pruebas a bajar el FreePascal? si mal no recuerdo ya tiene la clase de TStrings o TStringList,

otra opcion seria que hicieras el guardado de registros a mano, pero guardandolos como texto delimitado por comas, y donde cada registro es un renglon por ejemplo
"reg1campo1","reg1campo2","reg1Campo3","etc"
"reg2campo1","reg2campo2","etc","etc"

lo que si, es que es mas chamba, sin embargo, no dudo que haya por ahi una unidad ya hecha para leer y guardar datos en este formato...
Responder Con Cita
  #7  
Antiguo 08-06-2006
jonmendi jonmendi is offline
Miembro
 
Registrado: dic 2004
Posts: 110
Poder: 20
jonmendi Va por buen camino
gracis luisgutierrezb.
El free pascal ya lo tengo bajado, pero el problema es que el programilla que estoy haciendo yo lo tengo que importar a un proyecto bastante grande que está hecho en turbo pascal 7.0. Este proyecto he intentado pasarlo a free pascal, pero es más trabajo que matar una burra a pellizcos. por eso desistí.
Lo de los campos separados con comas tampoco me sirve, ya que tengo que dejar un fichero solo con los datos que yo le paso, pero sin comas ni nada. Si el registro es
Código:
  tRegistro = record
    nombre : string[15];
    apellido1 : string[30];
    telefono : string[9];
  end;
yo tengo que escribir en el fichero de texto
Código:
nnnnnnnnnnnnnnnaaaaaaaaaaaaaaaaaaaaaaaaaaattttttttt
y nada más que eso. Sin espacios ni comas ni nada de nada. El problema es que si tengo 2000 líneas de estas, y quiero modificar una, por distintos problemas de permisos y demás no puedo leer y escribir todo, por lo que no me srive un fichero de texto y usar readln writeln.
Muchas gracias a los que estáis mostrando tanto interés.
Un saludo
Jon
Responder Con Cita
  #8  
Antiguo 08-06-2006
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Pues se acabó lo que se daba, esto tiene que funcionar en Turbo pascal, ya que usa las funcionies de bajo nivel del sistema operativo.

Edito: Las funciones las pillo de SysUtils, pero estarán en otra unidad de Turbo Pascal. THandle es un Entero largo.

Código Delphi [-]
procedure TForm1.btn1Click(Sender: TObject);
var F:THandle;
    s: string[10];
    i:Integer;
begin
  if not sysutils.FileExists('c:\mio.txt') then
    F:= sysutils.FileCreate('c:\mio.txt')
  else
    f:= sysutils.FileOpen('c:\mio.txt',fmOpenReadWrite);

  if f>0  then
    ShowMessage('archivo abierto');

  s := 'texto 1';
  FileWrite(F,s,SizeOf(s));
  s := 'texto 2';
  FileWrite(F,s,SizeOf(s));
  s := 'texto 3';
  FileWrite(F,s,SizeOf(s));
  FileSeek(f,-(SizeOf(s)*2),1); // ir atrás en el fichero
{
  Al movernos tenemos que ir sumando los bytes que hay escritos
  realmente en el fichero. Multiplico por 2 para irme 2 "registros"
  hacia atrás, el primero es el "Texto 3", y al retroceder otro más
  me situo al principio de "texto 2", que se debe mostrar en el último
  ShowMessage
}
  FileRead(f,s,SizeOf(s));
  ShowMessage(s);
  FileClose(f);
end;
Espero que sea viable .

SAludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.

Última edición por Lepe fecha: 08-06-2006 a las 11:39:15.
Responder Con Cita
  #9  
Antiguo 08-06-2006
jonmendi jonmendi is offline
Miembro
 
Registrado: dic 2004
Posts: 110
Poder: 20
jonmendi Va por buen camino
muchas gracias lepe, pero.... me pasa solo a mi o en el archivo que crea escribe
Código:
texto 18@ texto 28@ texto 38@
a todo el mundo?
Precisamente son los "cuadraditos", las arrobas y demás signos los que quiero evitar.
No sé, estoy liado.
Un saludo y muchas grcias
Jon
Responder Con Cita
  #10  
Antiguo 08-06-2006
rafita rafita is offline
Miembro
 
Registrado: ago 2003
Ubicación: Cuenca- España.
Posts: 309
Poder: 21
rafita Va por buen camino
Hola Jonmendi,
No sé si me he perdido un poco con el tema, pero creo que lo estais complicando demasiado.

Lo que tu necesitas es un fichero de texto, no de un tipo concreto, de esa forma te pondrá los datos que necesitas uno tras otro, sin separadores de campo. Únicamente tendrá el caracter de fin de registro, lo cual no te dará ningún tipo de problema con la otra aplicación que debe leer ese fichero.

Con lo que sí tienes que tener cuidado es con completar el tamaño de los campos, ya que al no ir separados por nada tienen que tener su longitud exacta. Me explico con un ejemplo hecho de cabeza:
Código:
var MiNombre, MiApellido, MiTelefono, LoQueGrabo, Espacios : String;
     FDisco :  Text; 
begin
   // Inicializa la variable Espacios con 50 de caracteres en blanco
   Espacios:=StringOfChar(' ', 50);
   // en Pascal estándar sería algo así:
   // Espacios:='';
   // for i:=1 to 50 do Espacios:=Espacios+' ';
  
   // asignar el fichero de texto y crearlo nuevo
  AssignFile(FDisco,'TuFichero.txt'); // no olvides ponerle la ruta
  {$I-} Rewrite(FDisco); {$I+}       //  lo abro borrando todo lo que tiene
  if IOResult<>0 then                   // esto controlaba si había algún error
    begin 
       ShowMessage('No encuentro el fichero');
       Exit;
    end;
  // haz el bucle para ir encontrando los datos, y dentro de él grabas el fichero de texto
    // MiNombre:=......
    // MiApellido:=......
    // MiTelefono:=.....

   // completo la línea de texto a grabar uniendo los campos
   LoQueGrabo:=MiNombre+Copy(Espacios,1,15-Length(MiNombre))
                    +MiApellido+Copy(Espacios,1,30-Length(MiApellido))
                    +MiTelefono+Copy(Espacios,1,9-Length(MiTelefono));
  Writeln(FDisco,LoQueGrabo);
  // fin del bucle 

  // cierra el fichero generado
   CloseFile(FDisco);
Ahora mismo no recuerdo los sentencias exactas que se utilizan en pascal estándar para trabajar con ficheros de texto, pero me suena que son exactamente las mismas que estas utilizando para los ficheros con tipo, es decir: reset y rewrite para abrirlos, readln y writeln para leer o escribir una línea,... si necesitas información más exacta te busco un ejemplo hecho con Turbo Pascal.

Saludos
__________________
Rafita.
Responder Con Cita
  #11  
Antiguo 08-06-2006
jonmendi jonmendi is offline
Miembro
 
Registrado: dic 2004
Posts: 110
Poder: 20
jonmendi Va por buen camino
muchas gracias rafita!
si yo tb opino que me estoy liando, pero.... que no encuentro solución!
El código que me envías lo tengo probado, pero hay un problemilla: cuando abres un fichero de texto con reset(F), no puedes escribir en el mismo, solo leer. Si lo abro con rewrite(F) me borra todo lo que haya, cosa que tampoco me interesa (por distintos motivos de permisos etc etc...), y el append no me sirve porque yo quiero modificar una línea en concreto. Por eso creo que no puedo usar un archivo de texto. En basic se que había un put y get que hacian lo que yo quiero, pero en turbo pascal .... pues que no me sale!

Muchas gracias a todos. Y ya es jueves, así que animo.
Jon
Responder Con Cita
  #12  
Antiguo 09-06-2006
rafita rafita is offline
Miembro
 
Registrado: ago 2003
Ubicación: Cuenca- España.
Posts: 309
Poder: 21
rafita Va por buen camino
Hola Jon,

Vayamos por partes.

No recuerdo exactamente las características de los ficheros de texto en pascal, pero creo que tienes toda la razón: no permite modificar, tan solo abrir para leer y para escribir (borrando lo que tuviese). Sin embargo en los ficheros "con tipo" sí permitía acceder directamente a un registro y modificarlo.

Al leer tu primer mensaje de este hilo entendí que tú generabas el fichero, y que el problema era que fuese compatible con otra aplicación. Luego bastaba con generarlo correctamente (para no tener que modificar después ninguna lína), por eso te comente lo de los ficheros de texto.

Si en tu aplicación vas a tener que acceder a un registro concreto y modificarlo, se me ocurren varias posibilidades:

1ª) trabaja con un fichero "con tipo" (si puedes, mejor con una base de datos), y cuando necesites el fichero para comunicarte con la otra aplicación, lo generas como tipo texto.

2ª) prueba a trabajar con un fichero "con tipo", pero agrupando todos los campos en uno sólo (respetando las longitudes para poder codificarlo y decodificarlo), quizá así la otra aplicación no rechace el caracter de fin de campo.

3ª) si la modificación en un registro/línea va a ser algo puntual, puedes generarte el fichero de tipo texto y modificarlo "a mano" con cualquier editor de texto.

4ª) (trabajando con Delphi) si la modificación de los registros va a ser habitual, podrías generar el fichero de texto y utilizar (mediante Delphi) las posibilidades de reemplazar texto que te dan algunos procesadores de texto como Word (mira el apartado Server de este foro).

5ª) finalmente, puedes trabajar a lo bestia. Es decir, tienes tu fichero de texto (abierto con reset) que vas pasando a otro de trabajo (abierto con rewrite), cuando llegues a la línea a modificar, la cambias, y continuas procesando el fichero hasta llegar a final. Después les cambias los nombres o vuelves a pasar el contenido del fichero de trabajo al original. Esto es trabajar a lo bestia pero lo hace la máquina, y con los procesadores de hoy en día... tampoco será tanto tiempo.

Saludos Jon (y ánimo que ya es viernes)
__________________
Rafita.
Responder Con Cita
  #13  
Antiguo 09-06-2006
jonmendi jonmendi is offline
Miembro
 
Registrado: dic 2004
Posts: 110
Poder: 20
jonmendi Va por buen camino
muchas gracias rafita!
me parece que al final la solución me paece que va a ser algo parecido a la opción 5.
Muchas gracias a todos los que habéis demostrado interés.

Un slaudo, y no os derritais.
Jon
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Ayudaaaa!!! Tabla ASCII: El carácter Ñ vs. carácter ¥ Berto2003 Varios 5 26-07-2005 15:37:48
mainmenu y barritas de separación unreal4u Varios 2 22-04-2005 21:19:46
Caracter \r\n FRANKER Varios 3 03-06-2004 10:02:43
busqueda caracter a caracter Irina SQL 3 20-05-2003 13:12:53
sql a file jsanchez SQL 2 13-05-2003 21:34:03


La franja horaria es GMT +2. Ahora son las 11:22:08.


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
Copyright 1996-2007 Club Delphi