Pascal/Turbo Pascal - estudiante

   
Vista:

estudiante

Publicado por Federico (4 intervenciones) el 11/12/2007 06:39:21
Hola gente del foro
Me dirijo a ustedes para ver si me pueden ayudar con este problema que me esta volviendo loco...resulta que estoy estudiando ingenieria y una de las materias es informatica y bueno, nos hacen programar en pascal.
El asunto es que en unos dias hay que entregar el ultimo trabajo practico del año y yo todavia estoy
renegando con un error que me da el programa: el error 100 "disk read error".
Por lo que vi es bastante comun, pero no lo pude solucionar de las formas que se proponen generalmente q basicamete consisten en cabiar la ubicacion de los archivos...

Este es el codigo completo:

program tp2;

type

reg=record
nmed, year,mes: integer;
consumo: longint;
nombre: string[40];
descripcion: string[50];
end;
nombres= array[1..100]of string[40];
arre= array[1..100, 1..12] of longint;
numeros= array[1..100] of integer;

var
r: reg;
archi: file of reg;
num: numeros;
nomb: nombres;
i,j,n ,nm, camb_mes, cant_cli: integer;
A, B, CONSA, CONSB: arre;

PROCEDURE PROMEDIO (CONSB: ARRE; CANTCLI: INTEGER);

TYPE
PROME=ARRAY [1..12,1..2] OF REAL;

VAR
P: PROME;
J, I: INTEGER;
AUX: REAL;
BEGIN

FOR J := 1 TO 12 DO
BEGIN
FOR I := 1 TO CANT_CLI DO
BEGIN
P[I, 2] := P[I, 2] + CONSB[I, J];
END;

P[I, 2] := P[I, 2] / CANT_CLI;
P[I, 1] := J;
END;

FOR I := 1 TO 11 DO
BEGIN
FOR J := I+1 TO 12 DO
BEGIN
IF (P[I, 2] < P[J, 2]) THEN
BEGIN
AUX := P[I, 2];
P[I, 2] := P[J, 2];
P[J, 2] := AUX;
AUX := P[I, 1];
P[I, 1] := P[J, 1];
P[J,1] := AUX;
END;
END;
END;

FOR I := 1 TO 12 DO
BEGIN
WRITELN(' promedio mes ', P[I, 1], ':', P[I, 2]);
END;
END;

PROCEDURE COMPARATIVA_DE_MESES ( CONSA, CONSB: ARRE ; CANT_CLI: INTEGER; NOMB: NOMBRES);

VAR
CONTADOR, I, J: INTEGER;

BEGIN
CONTADOR:= 0;
FOR I := 1 TO CANT_CLI DO
BEGIN
FOR J := 1 TO 12 DO
BEGIN
IF (CONSB[I,J] < CONSA[I,J]) AND (CONSA[I,J] <> 0) AND (CONSB[I,J] <> 0) THEN;

CONTADOR := CONTADOR +1;
END;

WRITELN('el cliente : ', NOMB[I] , 'Num.: ', NUM[I], 'tuvo un menor consumo en', CONTADOR, 'meses');
END;
END;

PROCEDURE BUSQUEDA (NM: INTEGER; NUM: NUMEROS; NOMB: NOMBRES);

VAR
CONT, I: INTEGER;
BEGIN

CONT := 0;

REPEAT
CONT := CONT + 1;

UNTIL ( NM = NUM[CONT] ) OR (CONT = 100);

IF (CONT =100) AND (NM<> NUM[100]) THEN;
BEGIN
WRITELN ('no se encuentra el cliente especificado');
END;

WRITELN ('el cliente', NOMB[CONT],'numero', NUM[CONT], 'CONSUMIO:');

FOR I := 1 TO 12 DO
BEGIN
WRITELN ('mes', I, CONSB[CONT, I] );
END;
END;

begin
assign(archi, 'c:clientes.dat');
reset(archi);
i:=0;
while not(eof(archi)) do
begin
read(archi, r);

i:= i+1;
num[i]:= r.nmed;
nomb[i]:=r.nombre;

end;
close(archi);
i:= 0;
assign(archi, 'c:consumos.dat');
reset(archi);
while not(eof(archi)) do
begin
read(archi, r);
writeln(r.nmed, r.year,r.mes, r.consumo);
i:= i+1;
if (r.mes>camb_mes) then
i:= 0;
if (r.year = 2005) then
A[i,r.mes]:= r.consumo;
if (r.year = 2006) then
begin
B[i,r.mes]:= r.consumo;
end;
camb_mes:= r.mes;
end;
close(archi);

FOR I := 1 TO CANT_CLI DO
CONSA[I, 1] := A[I, 1];
CONSB[I, 1] := B[I, 1];
FOR J := 2 TO 12 DO
CONSA[I, J] := A[I, J] - A[I, J-1];
CONSB[I, J] := B[I, J] - B[I, J-1];

REPEAT
WRITELN ('si desea un listado del consumo promedio de cada mes del a¤o 2006, presione 1');

WRITELN ('para obtener un listado que contenga la cantidad de meses de 2006 en los cuales el consumo por cliente, presione 2');

WRITELN ('si desea ingresar un numero de medidor para consultar las cantidades consumidas en los meses del 2006, presione 3');

WRITELN ('si desea salir presione 4');

READ (N);

IF (N=1) THEN
PROMEDIO (CONSB, CANT_CLI);

IF (N=2) THEN
COMPARATIVA_DE_MESES (CONSA, CONSB, CANT_CLI, NOMB);

IF (N=3) THEN
BEGIN
WRITELN('ingrese numero del medidor');
READ (NM);

BUSQUEDA (NM, NUM, NOMB);
END;
UNTIL (N = 4);
END.

Gracias desde ya y un saludoo
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

RE:estudiante

Publicado por Diego Romero (997 intervenciones) el 11/12/2007 09:50:59
El error en tiempo de ejecución 100 puede deberse a:
- Leer un archivo cuyo lugar no es el correcto (path mal puesto).
- Intentar una lectura más allá del final del archivo.

Aparentemente ninguno de estos dos es tu caso pero como no tengo un "consumos.dat" ni "clientes.dat" para probar no lo puedo saber. Me da la impresión de que estás leyendo alguno de esos archivos pero éstos están vacíos (tamaño = 0). Pero como no nos dices en qué linea te marca el error, no puedo saber cuál de los dos archivos de datos es el "culpable".

Ahora bien, cambiando de tema. ¿Estás seguro de que esto:

FOR I := 1 TO CANT_CLI DO
CONSA[I, 1] := A[I, 1];
CONSB[I, 1] := B[I, 1];
FOR J := 2 TO 12 DO
CONSA[I, J] := A[I, J] - A[I, J-1];
CONSB[I, J] := B[I, J] - B[I, J-1];

es correcto?.
Hay dos asignaciones ahí que parece que deberían estar dentro de los respectivos for pero no lo están. ¿Comprendes lo que quiero decir?.
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

RE:estudiante

Publicado por Federico (4 intervenciones) el 11/12/2007 21:36:09
Mil gracias Diego por responder!
El error me lo da en la linea "read(archi, r);" correspondiente al archivo clientes.dat, que es el primer archivo que lee, asi que todabia puede fallar la lectura del segundo archivo...(que mal...).

Por si vos Diego, o alguien mas desea probar el programa aca dejo los links para descargar estos dos archivitos (que me los da la facu):

http://c-virtual.fceia.unr.edu.ar/location.cgi?wseccion=03&wid_archivo=03818&esMicrositio=no

http://c-virtual.fceia.unr.edu.ar/location.cgi?wseccion=03&wid_archivo=03820&esMicrositio=no

Con respecto a lo que mencionas al final "creeeeo" (asi con comillas por que no soy ningun gran programdor y encima como el programa todabia no lo pude hacer correr no estoy seguro de que esta todo bien) que es correcto por que las dos primeras asignaciones >>FOR I := 1 TO CANT_CLI DO
CONSA[I, 1] := A[I, 1];
CONSB[I, 1] := B[I, 1];
asignan datos a la primera columna de cada arreglo (consa y consb) y las que estan abajo del segundo for >>FOR J := 2 TO 12 DO
CONSA[I, J] := A[I, J] - A[I, J-1];
CONSB[I, J] := B[I, J] - B[I, J-1];
asignan datos a las columnas que van de la nº 2 hasta la 12.
El nº de filas esta dado por "cant_cli".
Lo tuve que hacer asi ya que los arreglos A Y B almacenan consumos acumulativos de un mes a otro y para almacenar los consumos netos en CONSA y CONSB respectivamente tuve que hacer la resta entre el mes a almacenar y el mes anterior pero al mes 1 no le puedo restar el mes anterior ya que no existe uno anterior...por eso lo asigno directmente sin hacer la resta ya que al ser el primer mes por mas acumulativo que sea el consumo este va a ser el consumo neto.
Eso es lo que deberia hacer el bloqe de codigo que vos mencionaste.
Espero que allas entendido algo aunque sea, es un lio de explicar por aca....

Salu2
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

RE:estudiante

Publicado por Diego Romero (997 intervenciones) el 12/12/2007 00:39:12
Me temo que los links que has puesto llevan a un sitio que requiere registración.

No, la verdad es que no entiendo qué haces en el bloque de código que te mencioné, solo quiero que notes que las líneas de código que señalo aquí más acabo se ejecutan una sola vez porque están fuera del for:

FOR I := 1 TO CANT_CLI DO
CONSA[I, 1] := A[I, 1];
CONSB[I, 1] := B[I, 1]; { <--- se ejecuta una sola vez }
FOR J := 2 TO 12 DO
CONSA[I, J] := A[I, J] - A[I, J-1];
CONSB[I, J] := B[I, J] - B[I, J-1]; { <-- se ejecuta una sola vez }
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

RE:estudiante

Publicado por Willy (181 intervenciones) el 12/12/2007 02:46:23
Hola Federico.

Tus archivos .dat no se pueden descargar.

Agregué a tu programa algunas líneas que crean los archivos solo para poder probarlo. Las líneas que yo agregué son:
114 a la 119 y
133 a la 139
No me dió ningun error 200. Supongo que tiene que ver con la forma en la que estás tratando de leer los archivos.

Noté que al entrar en la opción 1 de tu menú, da el siguiente error en la línea 40:
Error: 200.
Division by cero. Saludos!

program tp2;
type
reg=record
nmed, year,mes: integer;
consumo: longint;
nombre: string[40];
descripcion: string[50];
end;
nombres= array[1..100]of string[40];
arre= array[1..100, 1..12] of longint;
numeros= array[1..100] of integer;

var
r: reg;
archi: file of reg;
num: numeros;
nomb: nombres;
i,j,n ,nm, camb_mes, cant_cli: integer;
A, B, CONSA, CONSB: arre;
PROCEDURE PROMEDIO (CONSB: ARRE; CANTCLI: INTEGER);

TYPE
PROME=ARRAY [1..12,1..2] OF REAL;

VAR
P: PROME;
J, I: INTEGER;
AUX: REAL;
BEGIN

FOR J := 1 TO 12 DO
BEGIN
FOR I := 1 TO CANT_CLI DO
BEGIN
P[I, 2] := P[I, 2] + CONSB[I, J];
END;

P[I, 2] := P[I, 2] / CANT_CLI;
P[I, 1] := J;
END;

FOR I := 1 TO 11 DO
BEGIN
FOR J := I+1 TO 12 DO
BEGIN
IF (P[I, 2] < P[J, 2]) THEN
BEGIN
AUX := P[I, 2];
P[I, 2] := P[J, 2];
P[J, 2] := AUX;
AUX := P[I, 1];
P[I, 1] := P[J, 1];
P[J,1] := AUX;
END;
END;
END;

FOR I := 1 TO 12 DO
BEGIN
WRITELN(' promedio mes ', P[I, 1], ':', P[I, 2]);
END;
END;

PROCEDURE COMPARATIVA_DE_MESES ( CONSA, CONSB: ARRE ; CANT_CLI: INTEGER; NOMB: NOMBRES);

VAR
CONTADOR, I, J: INTEGER;

BEGIN
CONTADOR:= 0;
FOR I := 1 TO CANT_CLI DO
BEGIN
FOR J := 1 TO 12 DO
BEGIN
IF (CONSB[I,J] < CONSA[I,J]) AND (CONSA[I,J] <> 0) AND (CONSB[I,J] <> 0) THEN;

CONTADOR := CONTADOR +1;
END;

WRITELN('el cliente : ', NOMB[I] , 'Num.: ', NUM[I], 'tuvo un menor consumo en', CONTADOR, 'meses');
END;
END;

PROCEDURE BUSQUEDA (NM: INTEGER; NUM: NUMEROS; NOMB: NOMBRES);

VAR
CONT, I: INTEGER;
BEGIN

CONT := 0;

REPEAT
CONT := CONT + 1;

UNTIL ( NM = NUM[CONT] ) OR (CONT = 100);

IF (CONT =100) AND (NM<> NUM[100]) THEN;
BEGIN
WRITELN ('no se encuentra el cliente especificado');
END;

WRITELN ('el cliente', NOMB[CONT],'numero', NUM[CONT], 'CONSUMIO:');

FOR I := 1 TO 12 DO
BEGIN
WRITELN ('mes', I, CONSB[CONT, I] );
END;
END;

begin
assign(archi, 'c:clientes.dat');
ReWrite(archi);
For I := 1 to 20 do
begin
Seek(archi,I);
Write(archi,r);
end;
reset(archi);
i:=0;
while not(eof(archi)) do
begin
read(archi, r);

i:= i+1;
num[i]:= r.nmed;
nomb[i]:=r.nombre;

end;
close(archi);
i:= 0;
assign(archi, 'c:consumos.dat');
ReWrite(archi);
For I := 1 to 20 do
begin
Seek(archi,I);
Write(archi,r);
end;

reset(archi);
while not(eof(archi)) do
begin
read(archi, r);
writeln(r.nmed, r.year,r.mes, r.consumo);
i:= i+1;
if (r.mes>camb_mes) then
i:= 0;
if (r.year = 2005) then
A[i,r.mes]:= r.consumo;
if (r.year = 2006) then
begin
B[i,r.mes]:= r.consumo;
end;
camb_mes:= r.mes;
end;
close(archi);

FOR I := 1 TO CANT_CLI DO
CONSA[I, 1] := A[I, 1];
CONSB[I, 1] := B[I, 1];
FOR J := 2 TO 12 DO
CONSA[I, J] := A[I, J] - A[I, J-1];
CONSB[I, J] := B[I, J] - B[I, J-1];

REPEAT
WRITELN ('si desea un listado del consumo promedio de cada mes del a¤o 2006, presione 1');

WRITELN ('para obtener un listado que contenga la cantidad de meses de 2006 en los');
WRITELN ('cuales el consumo por cliente, presione 2');

WRITELN ('si desea ingresar un numero de medidor para consultar las cantidades consumidas en los meses del 2006, presione 3');

WRITELN ('si desea salir presione 4');

READ (N);

IF (N=1) THEN
PROMEDIO (CONSB, CANT_CLI);

IF (N=2) THEN
COMPARATIVA_DE_MESES (CONSA, CONSB, CANT_CLI, NOMB);

IF (N=3) THEN
BEGIN
WRITELN('ingrese numero del medidor');
READ (NM);

BUSQUEDA (NM, NUM, NOMB);
END;
UNTIL (N = 4);
END.
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

RE:estudiante

Publicado por Federico (4 intervenciones) el 12/12/2007 07:18:20
Si el sitio requiere registracion, pero pense que poniendo el link directamente a la parte de descarga....pero no funciono : (

Por si a alguien todabia le quedan ganas de ayudarme aqui pongo los inks para descarga directa desde uno de esos sevidores para subir archivos:

http://www.ultrashare.net/hosting/fl/67f4b37e8a/CLIENTES
http://www.ultrashare.net/hosting/fl/7c8240d122/CONSUMOS

Estare infinitamente agradecido si alguien me dice la causa del error. Si no no se que hare con este trabajo practico...

@ Diego: es como vos decis....me olvide los begin y end!!! suerte que no es ing. en sistemas lo que estdio, sino creo que deberia buscar otra profesion ¿no?

@ Willy: claro el error tiene que ver con la lectura del archivo -error 100 disk read error- pero no se como solucionarlo... y creo que te dio ese error a vos por que la opcion uno hace un promedio, dividiendo por la variable cant_cli (cantidad de clientes)que en el archivo que vos creaste debe ser cero supongo.

muchas gracias a los dos.
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

RE:estudiante

Publicado por Willy (181 intervenciones) el 13/12/2007 03:59:52
Hola de nuevo Federico.

Creo que ya descubrí dónde está el error de tu programa. Observa esto:

reg=record
nmed, year,mes: integer;
consumo: longint;
nombre: string[40];
descripcion: string[50];
end;

Fíjate bien!. La variable r es de tipo reg; lo que significa que cuando pones:

read(archi, r);

se leen del archivo los datos: nmed, year,mes, consumo, nombre, descripcion y se almacenan en r
Es cierto que este "read" esta encerrado detro del ciclo While not eof(archi)
Es posible que llegue un momento en el que el apuntador del archivo todavía no ha llegado al final del archivo pero los datos que faltan por leer ya no son suficientes para "llenar" toda la variable r. Recuerda que se debe llenar: r.nmed, r.year, r.nombre, etc..

No se si me explico, pero aunque la forma en que solucioné esto podría no ser la ideal, cambié el ciclo while por un: repeat until FilePos(archi) = fileSize(archi)-1;
lo que hace que se deje de leer el programa hasta que se llegue a la penúltima linea.

Hice una marca: ********** Donde está la midificación. Línea 118.

Espero haberte ayudado un poco. Saludos!

-------------------------------------------------------------------------------

program tp2;
uses Crt;
type

reg=record
nmed, year,mes: integer;
consumo: longint;
nombre: string[40];
descripcion: string[50];
end;
nombres= array[1..100]of string[40];
arre= array[1..100, 1..12] of longint;
numeros= array[1..100] of integer;

var
r: reg;
archi: file of reg;
num: numeros;
nomb: nombres;
i,j,n ,nm, camb_mes, cant_cli: integer;
A, B, CONSA, CONSB: arre;

PROCEDURE PROMEDIO (CONSB: ARRE; CANTCLI: INTEGER);

TYPE
PROME=ARRAY [1..12,1..2] OF REAL;

VAR
P: PROME;
J, I: INTEGER;
AUX: REAL;
BEGIN

FOR J := 1 TO 12 DO
BEGIN
FOR I := 1 TO CANT_CLI DO
BEGIN
P[I, 2] := P[I, 2] + CONSB[I, J];
END;

P[I, 2] := P[I, 2] / CANT_CLI;
P[I, 1] := J;
END;

FOR I := 1 TO 11 DO
BEGIN
FOR J := I+1 TO 12 DO
BEGIN
IF (P[I, 2] < P[J, 2]) THEN
BEGIN
AUX := P[I, 2];
P[I, 2] := P[J, 2];
P[J, 2] := AUX;
AUX := P[I, 1];
P[I, 1] := P[J, 1];
P[J,1] := AUX;
END;
END;
END;

FOR I := 1 TO 12 DO
BEGIN
WRITELN(' promedio mes ', P[I, 1], ':', P[I, 2]);
END;
END;

PROCEDURE COMPARATIVA_DE_MESES ( CONSA, CONSB: ARRE ; CANT_CLI: INTEGER; NOMB: NOMBRES);

VAR
CONTADOR, I, J: INTEGER;

BEGIN
CONTADOR:= 0;
FOR I := 1 TO CANT_CLI DO
BEGIN
FOR J := 1 TO 12 DO
BEGIN
IF (CONSB[I,J] < CONSA[I,J]) AND (CONSA[I,J] <> 0) AND (CONSB[I,J] <> 0) THEN;

CONTADOR := CONTADOR +1;
END;

WRITELN('el cliente : ', NOMB[I] , 'Num.: ', NUM[I], 'tuvo un menor consumo en', CONTADOR, 'meses');
END;
END;

PROCEDURE BUSQUEDA (NM: INTEGER; NUM: NUMEROS; NOMB: NOMBRES);

VAR
CONT, I: INTEGER;
BEGIN

CONT := 0;

REPEAT
CONT := CONT + 1;

UNTIL ( NM = NUM[CONT] ) OR (CONT = 100);

IF (CONT =100) AND (NM<> NUM[100]) THEN;
BEGIN
WRITELN ('no se encuentra el cliente especificado');
END;

WRITELN ('el cliente', NOMB[CONT],'numero', NUM[CONT], 'CONSUMIO:');

FOR I := 1 TO 12 DO
BEGIN
WRITELN ('mes', I, CONSB[CONT, I] );
END;
END;

begin
ClrScr;
assign(archi, 'c:clientes.dat');
reset(archi);
i:=0;
Repeat *************
read(archi, r);

i:= i+1;

num[i]:= r.nmed;
nomb[i]:=r.nombre;

WriteLn(num[i]);
WriteLn(nomb[i]);
until FilePos(archi) = fileSize(archi)-1;

close(archi);
i:= 0;
assign(archi, 'c:consumos.dat');
reset(archi);
Repeat
read(archi, r);
writeln(r.nmed, r.year,r.mes, r.consumo);
i:= i+1;
if (r.mes>camb_mes) then
i:= 0;
if (r.year = 2005) then
A[i,r.mes]:= r.consumo;
if (r.year = 2006) then
begin
B[i,r.mes]:= r.consumo;
end;
camb_mes:= r.mes;
Until FilePos(archi) = fileSize(archi)-1;

close(archi);

FOR I := 1 TO CANT_CLI DO
CONSA[I, 1] := A[I, 1];
CONSB[I, 1] := B[I, 1];
FOR J := 2 TO 12 DO
CONSA[I, J] := A[I, J] - A[I, J-1];
CONSB[I, J] := B[I, J] - B[I, J-1];

REPEAT
WRITELN ('si desea un listado del consumo promedio de cada mes del a¤o 2006, presione 1');

WRITELN ('para obtener un listado que contenga la cantidad de meses de 2006 en los');
Writeln('cuales el consumo por cliente, presione 2');

WRITELN ('si desea ingresar un numero de medidor para consultar las cantidades consumidas en los meses del 2006, presione 3');

WRITELN ('si desea salir presione 4');

READ (N);

IF (N=1) THEN
PROMEDIO (CONSB, CANT_CLI);

IF (N=2) THEN
COMPARATIVA_DE_MESES (CONSA, CONSB, CANT_CLI, NOMB);

IF (N=3) THEN
BEGIN
WRITELN('ingrese numero del medidor');
READ (NM);

BUSQUEDA (NM, NUM, NOMB);
END;
UNTIL (N = 4);
END.
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

RE:estudiante

Publicado por Federico (4 intervenciones) el 14/12/2007 22:09:30
Muchsimass gracias willy!!
La verdad que el prog. aun no anda, pero al menos lee el archivo sin errores jeje

Un abrazo
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