Pascal/Turbo Pascal - ¿Cómo guardar registros en pascal? en lazarus

 
Vista:
sin imagen de perfil
Val: 2
Ha disminuido su posición en 2 puestos en Pascal/Turbo Pascal (en relación al último mes)
Gráfica de Pascal/Turbo Pascal

¿Cómo guardar registros en pascal? en lazarus

Publicado por sebastian (1 intervención) el 13/10/2020 04:33:09
estoy tratando de guardar un registro en un archivo de texto, pero soy nuevo en pascal y realmente no entiendo cómo hacer este proceso. Me explico:

Tengo un formulario donde quiero agregar 5 alumnos, en el record la información se llena por alumno y con un array trato de guardar la información de 5 alumnos y separarla por equipos (hasta 10 equipos). Entiendo cómo hacer ese registro, revisarlo y asignarle valor a los campos, mi problema es que no sé cómo guardarlo correctamente.

No sé si un archivo de texto puede contener un array que tenga un registro dentro con campos de varios tipos. Realmente agradecería su orientación, acabo de comenzar en pascal.

Esto es lo que he hecho:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
type
  alumnos = record
    nombre,apellido:string[60];
    id,tiempoA,tiempoB,tiempoT,promedio,lapsoA,lapsoB,lapsoC:integer;
  end;
 
var
  datos: array[1..5]of alumnos;
 
procedure TForm3.ingresarEquipoClick(Sender: TObject);
var
  tA,tB,lA,lB,lC,prom:integer;
begin
  if (nombre1.text<>'') and (apellido1.text<>'') and (tiempoA1.text<>'') and
     (tiempoB1.text<>'') and (lapsoA1.text<>'') and (lapsoB1.text<>'') and
     (lapsoC1.text<>'') then
  begin
    AssignFile(tDatos,'datos.txt');
    rewrite(tDatos);
 
    {Guardo la informacion de un estudiante por ahora}
 
    tA:=StrToInt(tiempoA1.text);
    tB:=StrToInt(tiempoB1.text);
    lA:=StrToInt(lapsoA1.text);
    lB:=StrToInt(lapsoB1.text);
    lC:=StrToInt(lapsoC1.text);
 
    datos[1].id:=1;
    datos[1].nombre:=nombre1.text;
    datos[1].apellido:=apellido1.text;
    datos[1].tiempoA:=tA;
    datos[1].tiempoB:=tB;
    datos[1].tiempoT:=tA+tB;
    datos[1].lapsoA:=lA;
    datos[1].lapsoB:=lB;
    datos[1].lapsoC:=lC;
 
    write(tDatos,datos);
    closeFile(tDatos);
 
  end
else
  begin
    ShowMessage('Insert content');
  end;
end;

Me suelta este error: unit3.pas (147,24) Error: Incompatible types: got "Array [1..5] Of alumnos" expected "alumnos".

Y si cambio write(tDatos,datos) por write(tDatos,alumnos), me dice: unit3.pas (147,26) Error: Can't read or write variables of this type

El proyecto que busco lograr es crear un programa que pueda ingresar 10 equipos de 5 alumnos cada uno donde se conozca el nombre, apellido, tiempo de carrera a 200m (tiempoA), tiempo de carrera a 1500m (tiempoB), la suma de estos dos tiempos (tiempoT), las notas de cada lapso (lapsoA, lapsoB, lapsoC) y el promedio (la suma de los lapsos entre 3). Al ingresar los equipos hay que validar que los estudiantes de dicho equipo no pasen un tiempo límite para cada carrera, ya que si se pasa alguno, el equipo completo queda descalificado.

Trabajando con los equipos calificados, hay que determinar el tiempo total por equipo (sumando cada tiempoT de cada miembro) y encontrar el que haya tenido menor tiempo. Si se da el caso de que el equipo con menor tiempo tenga alumnos con un promedio menor a 16, se debe dar la opción de eliminar y agregar alumnos.

Eso es básicamente lo que requiere el programa. Espero me ayuden con alguna cosa. Gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 112
Bronce
Ha mantenido su posición en Pascal/Turbo Pascal (en relación al último mes)
Gráfica de Pascal/Turbo Pascal

Aqui tienes un ejemplo

Publicado por juanba (40 intervenciones) el 21/10/2020 11:17:25
Hola.
He mirado el código que presentas y solucionar el error es fácil. No veo cómo has declarado la variable tDatos pero me imagino que será un FILE of alumnos. Entonces es necesario que las variablesque utilices para leer o escribir en el archivo sean de tipo alumnos y si cambias la instruccion write(tDatos, datos) por write(tDatos, datos[1]) te archivara correctamente el primer elemento del array.
Te he modificado la rutina de archivado y he añadido otra de lectura para que te sirvan de referencia. Todo en Lazarus que es en lo que estas trabajando. EL formulario tiene un spinedit que permite seleccionar el registro de alumno del array entre 1 y 5. Puedes cambiarlo por cualquier otro control similar que te convenga mejor.

La ventana quedaría asi:

RegAlumnos

El código de introducción de registros de un alumno:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Procedure TForm3.ingresarequipoClick(Sender: TObject);
var
  tDatos: FILE of alumnos;
  tA,tB,lA,lB,lC,prom:integer;
  i, NumAlumno: integer;
begin
  if (nombre1.text<>'') and (apellido1.text<>'') and (tiempoA1.text<>'') and
     (tiempoB1.text<>'') and (lapsoA1.text<>'') and (lapsoB1.text<>'') and
     (lapsoC1.text<>'') then
  begin
    NumAlumno := SpAlumno.Value;
    AssignFile(tDatos,'datos.txt');
    rewrite(tDatos);
    {Guardo la informacion de un estudiante por ahora}
    tA:=StrToInt(tiempoA1.text);
    tB:=StrToInt(tiempoB1.text);
    lA:=StrToInt(lapsoA1.text);
    lB:=StrToInt(lapsoB1.text);
    lC:=StrToInt(lapsoC1.text);
{ Tal como funciona este procedimiento no hace falta que "datos" sea un array.
  Con una variable de tipo "alumnos" bastaria. Pero lo dejo por si más adelante
  hace falta}
    datos[NumAlumno].id:=1;
    datos[NumAlumno].nombre:=nombre1.text;
    datos[NumAlumno].apellido:=apellido1.text;
    datos[NumAlumno].tiempoA:=tA;
    datos[NumAlumno].tiempoB:=tB;
    datos[NumAlumno].tiempoT:=tA+tB;
    datos[NumAlumno].lapsoA:=lA;
    datos[NumAlumno].lapsoB:=lB;
    datos[NumAlumno].lapsoC:=lC;
 
    for i := 1 to 5 do
      write(tDatos,datos[i]);
 
{   O alternativamente, si no se quiere guardar todo el array...
    Usar el archivo para un unico registro de alumnos
  write(tDatos, datos[NumAlumno]);
}
    closeFile(tDatos);
  end
else
  begin
    ShowMessage('Insert content');
  end;
end;

Y el código de lectura de los alumnos del archivo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//------------------------------------------------------------------------------
// BtnRecupClick
// Lee el contenido del archivo datos.txt en un array y visualiza el registro
// que se haya preseleccionado en el SpinEdit
//------------------------------------------------------------------------------
Procedure TForm3.BtnRecupClick(Sender: TObject);
var
  tDatos: FILE of alumnos;
  i, NumAlumno: integer;
Begin
  NumAlumno := SpAlumno.Value;
  AssignFile(tDatos,'datos.txt');
  reset(tDatos);
  for i := 1 to 5 do
    read(tDatos, datos[i]);
 
  with datos[NumAlumno] do
  begin
    nombre1.Text := nombre;
    apellido1.Text := apellido;
    tiempoA1.Text := IntToStr(tiempoA);
    tiempoB1.Text := IntToStr(tiempoB);
    lapsoA1.Text := IntToStr(lapsoA);
    lapsoB1.Text := IntToStr(lapsoB);
    lapsoC1.Text := IntToStr(lapsoC);
  End;
  closeFile(tDatos);
end;

Y ahora, algunos comentarios sin intención de molestar:
1) Es conveniente usar el estilo de escritura y las convenciones de nomenclatura de identificadores que se usan en Lazarus y en Delphi. Por ejemplo, los nombres de tipo deben empezar por T mayuscula: por ejemplo TRecAlumnos. Del primer vistazo se aprecia que es un tipo de record y que contiene datos de alumnos o de lo que sea. Puedes encontrar en la red otros ejemplos de estas convenciones.
2) Has usado el nombre datos.txt para un archivo que no es de texto sino binario. Esto puede inducir a confusión si en el futuro otra persona o tu mismo vuelves a examinar el codigo y asumes que datos.txt es por supuesto un fichero de texto. Porque no lo es. Estaria mejor, por ejemplo Alumnos.bin.
3) La instruccion StrToInt es muy cómoda de usar para convertir strings con contenido numerico a integers pero tiene el problema de que lanza una excepcion si el parametro no se puede convertir. Por ejemplo, si un usuario introduce en la casilla de Tiempo-A el valor veinte el programa le emitirá una excepcion con un texto más o menos como este: "veinte" is not a valid integer. Lo cual puede tener significado para el operario o puede que no. Tendrías que atrrapar la excepcion o bien usar StrToIntDef que no emite excepciones. Por ejemplo

1
2
3
4
5
tA:=StrToIntDef(tiempoA1.text, -1);
   if tA < 0 then
{
  Presentar tu propio mensaje de error
}

Espero que estos comentarios te ayuden y si necesitas algo más, mandame un mensaje e intentaré solucionarte lo que pueda.
Suerte.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar