[ Foro de Pascal ]

archivos

04-Jan-2014 17:20
natalia tavora
14 Respuestas

Hola, mi nombre es natalia, soy estudiante de 1er año  de la carrera de analista en sistemas, estoy haciendo el juego de palabras revueltas, pero me cuesta la parte de archivos hice  un procedimiento para crear usuarios que seria mas o menos asi...


Procedure Crear_Usuarios(r_usuarios:Usuarios);
	var
	p:integer;
begin
	
	p:=filesize(f_user);
	gotoxy(25,7); writeln('ingrese nombre de usuario:');
	readln(r_usuarios.id);
	gotoxy(25,9); writeln('Ingrese password:');
	gotoxy(25,11); writeln('(numeros y letras, maximo 8 caracteres)');
	readln(r_usuarios.Password);
	read(F_user,r_usuarios);
end;


pero cuando ejecuto el programa y voy a la parte de crear usuarios, me saca del programa.... porque puede ser?


04-Jan-2014 17:24
natalia tavora

aca  esta el codigo completo...


Program juegodepalabras;
	Uses crt,sysutils;
	type
		Usuarios=record
			id:string;
			password:string[8];
			puntos:integer;
		end;	
	var
		Op:Integer;
		Idioma,Op2:Char;
		r_usuarios:Usuarios;
		F_user:file of Usuarios;
	procedure abrir_archivo();
	begin
	
      assign(F_user,'C:\usuariosregistrados.dat');
	  if (FileExists('C:\usuariosregistrados.dat')=false)then
		Begin
			rewrite(F_user);
		end;
	end;
Procedure Crear_Usuarios(r_usuarios:Usuarios);
	var
	p:integer;
begin
	
	p:=filesize(f_user);
	gotoxy(25,7); writeln('ingrese nombre de usuario:');
	readln(r_usuarios.id);
	gotoxy(25,9); writeln('Ingrese password:');
	gotoxy(25,11); writeln('(numeros y letras, maximo 8 caracteres)');
	readln(r_usuarios.Password);
	read(F_user,r_usuarios);
end;
	procedure Recuadro_principal(color:integer);
	VAR
	I:INTEGER;
	BEGIN
	TEXTCOLOR(COLOR);
	for I :=1 to 80 do
	begin
		gotoxy(I,1);
		write('?');
		gotoxy(I,24);
		write('?');
	end;
	for I :=1 to 24 do
	begin
		 gotoxy(1,I);
		 write('?');
		 gotoxy(80,I);
		 write('?');
	end;
		 gotoxy(80,1);write('?');//?
		 gotoxy(80,24);write('?');//?
		 gotoxy(1,1);write('?');//?
		 gotoxy(1,24);write('?');//?
	 end;
Procedure rules();
Begin
	clrscr;
	Recuadro_principal(white);
	TextColor(Yellow);
	GOTOXY(20,3); WRITELN ('Reglas:');
	TextColor(white);	
	gotoxy(7,5);WRITELN ('Cantidad de jugadores maximo: 2.');
	gotoxy(7,7);WRITELN ('El juego consiste en averiguar una palabra que está desordenada.');
	gotoxy(7,9);WRITELN ('Por cada palabra obtendra un puntaje:');
	gotoxy(7,11);WRITELN ('Si la palabra fue obtenida en el primer intento obtiene 100 puntos.');
	gotoxy(7,13);WRITELN ('Si la palabra fue obtenida en el segundo intento obtiene 75 puntos.');
	gotoxy(7,15);WRITELN ('Si la palabra fue obtenida en el tercer intento obtiene 50 puntos.');
	gotoxy(7,17);WRITELN('Si no acerto en ninguno de los 3 intentos se le descuentan 50 puntos... ');
	textcolor(Yellow);
	gotoxy(15,19);writeln('Presione enter para volver al menu principal...');
	readln();
End;
	 Procedure creditos ();
Begin
	clrscr;
	Textcolor(Yellow);
	Gotoxy(24,3);writeln('Este programa es presentado por:');
	Textcolor(white);
	Gotoxy(25,7);writeln('Javier Echagüe y Natalia Tavora ');
	Gotoxy(25,9);writeln('Estudiantes del instituto Hilet ');
	Gotoxy(25,11);writeln('1° año De la carrera Analista de Sistemas ');
	Textcolor(11);
	Gotoxy(25,13);writeln('Mar del Plata, Buenos Aires');
	Gotoxy(25,15);writeln('Republica Federal Argentina');
	textcolor(Yellow);
	gotoxy(15,19);writeln('Presione enter para volver al menu principal...');
	readln();
End;
	 procedure parpadeo(palabra:string;fila,columna:integer);
var
i:integer;
begin
for i:=0 to 2 do
	begin
		textcolor(yellow);
		gotoxy(fila,columna); writeln(palabra);
		delay(100);
		textcolor(red);
		gotoxy(fila,columna); writeln(palabra);
		delay(100);
		textcolor(yellow);
		gotoxy(fila,columna); writeln(palabra);
		delay(100);
		textcolor(red);
		gotoxy(fila,columna); writeln(palabra);
		delay(100);
	end;
end;
procedure Muevepalabra(palabra:string;fila,columna:integer);
	var
	cant,i:integer;
begin
	cant:=length(palabra);
	for i:=0 to cant do
	begin
		clrscr;
		gotoxy(fila+i,columna); writeln(palabra);
		delay(100);
	end;
end;
procedure Maquina_de_escribir(palabra:string;color,fila,columna:integer);
	var
	z,i:integer;
begin
	z:=length(palabra);
	for i:=1 to z do
	begin
		textcolor(color);
		gotoxy(fila+i,columna); writeln(palabra[i]);
		delay(100);
		
	end;
end;
Procedure presentacion ();
	begin
		clrscr;
		Maquina_de_escribir('Javier Echague',2,15,15);
		clrscr;
		parpadeo('and',25,15);
		Clrscr;
		Maquina_de_escribir('Natalia Tavora',12,19,12);
		clrscr;
		Muevepalabra('Presentan',1,3);
		clrscr;
		Maquina_de_escribir('El Juego',15,15,5);
		Maquina_de_escribir('de',15,19,7);
		Muevepalabra('Palabras revueltas',1,9);
		parpadeo('Presione Enter...',25,15);
		readln;
	end;
procedure cambiacolor(op:integer);
	var
		i: integer;
Begin

repeat

    TextColor(op);
  case (op) of

	   1:begin
			TextBackGround(1);
		end;
	   2:begin
			TextBackGround(2);
		end;
	   3: begin
			TextBackGround(3);
		end;
	   4:begin
			TextBackGround(4);
		end;
	   5 :begin
			TextBackGround(5);
		end;
	   6: begin
			TextBackGround(6);
		end;
	End;
  clrscr;
 until ((op>=1) and (op<=8));
end;
	procedure cargando(palabra:string);
		var
		i,a:integer;
	begin
		clrscr;
		gotoxy(24,10); writeln('<');
		gotoxy(36,10); writeln('>');
		a:=0;
		for i:=1 to 10 do
		begin
			textcolor(white);
			gotoxy(25+i,10); writeln('?');
			a:=a+10;
			gotoxy(25,12); writeln(palabra,a,'%');
			delay(150);
		end;
	end;
	procedure mlista();
	var
	i:integer;
Begin
	clrscr;
	Recuadro_principal(white);
	gotoxy(15,7);writeln('SELECCIONE UN FONDO PREDETERMINADO');
	for i:=1 to 6 do
	begin
		gotoxy(25,8+i);
		textcolor(0+i);
		writeln(0+i,':Fondo');
	end;
	textcolor(white);
	gotoxy(25,20);
	writeln('Su Eleccion es: ');
	gotoxy(42,20);
END;
	Procedure Mostrar_Menu_Principal();
		Begin
			clrscr;
			Recuadro_principal(white);
			gotoxy(16,3);writeln('Seleccione una opcion Segun corresponda');
			gotoxy(25,5);writeln('0: Salir');
			gotoxy(25,7);writeln('1: Opciones');
			gotoxy(25,9);writeln('2: Ver las reglas del Juego');
			gotoxy(25,11);writeln('3: Jugar');
			gotoxy(25,13);writeln('4: Ver Creditos');
			gotoxy(25,15);writeln('Su Eleccion es: ');
			gotoxy(42,15);
		End;
		Procedure Mostrar_Menu_Opciones();
		Begin
			clrscr;
			Recuadro_principal(white);
			gotoxy(16,3);writeln('Seleccione una opcion Segun corresponda');
			gotoxy(25,5);writeln('1: Seleccionar idioma');
			gotoxy(25,7);writeln('2: Cambiar fondo');
			gotoxy(25,9);writeln('3: Crear Usuario');
			gotoxy(25,11);writeln('4: Volver al menu principal');
			gotoxy(25,13);writeln('Su Eleccion es: ');
			gotoxy(42,13);
		End;
		Procedure Mostrar_Menu_Cambiar_idioma();
		Begin
			clrscr;
			Recuadro_principal(white);
			gotoxy(15,3);writeln('Seleccione un idioma');
			gotoxy(15,5);writeln('E: Espa±ol');
			gotoxy(15,7);writeln('I: Ingles');
			gotoxy(15,9);writeln('V: Volver al menu principal');
			gotoxy(15,11);writeln('Su Eleccion es: ');
			gotoxy(42,11);
		End;
		procedure func_menuopciones(var idioma:char;op:integer;r_usuarios:Usuarios);
		
		Begin
			Case op of
			1:	Begin
					repeat
						Mostrar_Menu_Cambiar_idioma();
						readln(idioma);
						idioma:=upcase(idioma);
					until(idioma='E') or (idioma='I')or (idioma='V');
				end;
			2:	Begin
					repeat
						mlista();
						readln(op);
						cambiacolor(op);
					until ((op>=1) or (op<=6));
				end;
			3:	Begin
					clrscr;
					Crear_Usuarios(r_usuarios);
				end;
			4:	Begin
					clrscr;
					Mostrar_Menu_Principal();
				end;
		end;
		end;
procedure func_menuprincipal(var op:integer);
	Begin
		case op of
		0: Begin
				clrscr;
				gotoxy(15,13);
				writeln('Saliendo del sistema...');
				delay(600);
			End;
		1: begin
				Mostrar_Menu_Opciones();
				readln(op);
				func_menuopciones(idioma,op,r_usuarios);	
			end;
		2: begin
				rules();
			end;
		3: begin
				cargando('Cargando...');
			end;
		4: begin
				creditos ();
			end;
	end;
		End;
BEGIN
abrir_archivo();
clrscr;
presentacion ();
repeat
	repeat
		Mostrar_Menu_Principal();
		readln(op);
		func_menuprincipal(op);
	until (op>=0) or (op<=4);
until(op=0);	
close(F_user);
END.



04-Jan-2014 21:21
Nacho Cabanes (+83)

Es que miras el tamaño del fichero con "filesize",  pero no usas el valor obtenido, de modo que puedes estar intentando leer de un fichero vacío.

De hecho, no abres ni cierras el fichero desde dentro de ese procedimiento, lo que es una causa muy frecuente de problemas: deberías intentar que todos los datos sean "tan locales como sea posible". De hecho, el error exacto que yo recibo al probarlo es File not open al entrar a la opción 3 del menú de Opciones.

Aun así, también hay algún detalle de lógica que no comprendo, porque (por ejemplo) el procedimiento Crear_usuarios no crea (escribe) nada, sino que sólo lee de fichero.


04-Jan-2014 23:49
Luis Torres (+18)

Efectivamente cuando elegimos la opción "Crear usuario" del menú "Opciones" no creamos ningún usuario, simplemente leemos lo que hemos introducido en el archivo. En vez de usar read, deberías usar write(f_user,r_usuario);

Pero el problema no está allí unicamente. Cuando ejecuto la opción de "Crear usuario" abruptamente se sale de la ejecución del programa, esto se produce porque estás utilizando la instrucción de contar el número de registros (filesize) del archivo, sin siquiera haberlo abierto el archivo. Tienes un procedimiento llamado abrir_archivo que podrías utilizar, y luego debes abrirlo para la lectura o para la escritura según sea el caso (reset(r_user) o rewrite(r_user)). Una vez realizadas las operaciones sobre los archivos siempre debes cerrarlos (close(r_user)).

En el caso de tu programa, yo me imagino que quieres registrar varios usuarios en distintas ocasiones, o sea uno hoy y otro probablemente mañana o pasado mañana, y quieres que esos usuarios permanezcan guardados en el archivo. Pascal no te permite agregar un registro a una archivo que ya contiene otros registros, pero hay una técnica, muy sencilla, que se aplica para lograr hacerlo. Debes investigarla para poder realizar tu programa.

Yo modifiqué el procedimiento, pero sólo se pueden guardar un solo usuario, para guardar varios debes investigar la técnica de la que te hablé anteriormente.

Aquí está el código:


Procedure Crear_Usuarios(r_usuarios:Usuarios);
	var
	p:integer;
begin
        writeln('Estoy en Crear Usuarios.');readln;
        abrir_archivo();
        reset(f_user); {en realidad hay que usar rewrite(f_user), pero funciona no sé porqué razón}
        writeln('Ya abri el archivo.'); readln;
        p:=filesize(f_user);
        writeln('Ya conte el numero de registros: ',p); readln;
	gotoxy(25,7); writeln('ingrese nombre de usuario:');
	readln(r_usuarios.id);
	gotoxy(25,9); writeln('Ingrese password:');
	gotoxy(25,11); writeln('(numeros y letras, maximo 8 caracteres)');
	readln(r_usuarios.Password);
        writeln('Se introdujo: ',r_usuarios.id);
        writeln('La contrasena es: ',r_usuarios.Password);
        readln();
        write(f_user,r_usuarios);
        writeln('Logre guardar el dato');
        readln();
        close(f_user);
        writeln('Logre cerrar el archivo.');
        readln();
       {read(F_user,r_usuarios);}
end;


Saludos.


05-Jan-2014 15:50
natalia tavora

(nacho) es que abro el fichero en el programa principal, y lo cierro al final del programa, si lo abriría en el procedimiento ese me tiraria un error porque el archivo ya esta abierto no?
la idea del procedimiento es primero corroborar si ese usuario ingresado existe o no, si existe en lugar de grabarlo le pide que cree uno con otro nombre porque lo de los usuarios es para que cada vez que un usuario juegue empieze con los puntos que ya gano.... entonces lo que quería hacer con filesize era primero si el filesize=0 que lo grabe directamente porque seria el primer usuario, y si es distinto de cero que busque en los usuarios existentes si existe o no ese usuario, pero como cuando seleccione la opción de crear usuarios me sacaba, no continue con el procedimiento....


05-Jan-2014 16:01
natalia tavora

seria mas o menos asi


Procedure Crear_Usuarios(r_usuarios:Usuarios);
	var
	p:integer;
usuarios,pasword:string;
begin
 
	p:=filesize(f_user);
	gotoxy(25,7); writeln('ingrese nombre de usuario:');
	readln(usuarios);
	gotoxy(25,9); writeln('Ingrese password:');
	gotoxy(25,11); writeln('(numeros y letras, maximo 8 caracteres)');
	readln(Password);
if (p<>0) then
begin
i:=0;
       while ((i<=p) and (usuarios<>r_user.usuarios))do
   
           Begin
                  if (usuarios=r_user.usuarios)then
                        writeln('el usuario ya existe, ingrese otro nombre de usuario');
                  else
                        (aca es donde grabaria el usuario en el archivo, pero no se como hacerlo);  
           end;
end;
	read(F_user,r_usuarios);
end;



05-Jan-2014 16:24
Nacho Cabanes (+83)

Tienes las nociones básicas de ficheros con tipo aquí:
http://www.aprendeaprogramar.com/mod/resource/view.php?id=224

En tu caso, deberías leer un nuevo dato dentro del "while", no fuera de él:


while ((i<=p) and (usuarios<>r_user.usuarios))do
Begin
    read(F_user,r_usuarios);
    if (usuarios = r_user.usuarios) then ...


Y no puedes guardar datos hasta el final, NO debes hacerlo en el "else", porque no sabes seguro que el dato no está con sólo mirar un dato, sino que debes esperar hasta haber comprobado todos ellos.

En general, para añadir datos deberías ir al final (con "seek") y entonces escribir (con "write"). (Insisto, mira el apartado 11.3 del curso).

En tu caso, si no has encontrado el dato, ya estarías al final del fichero, de modo que no necesitas el "seek", y bastaría con crear un dato de tipo "Usuarios" (que contenga el nombre y el password que ha escogido el usuario) y que lo guardaras con "write".

(Y es mala costumbre esa de abrir el fichero al principio del programa y cerrarlo al final, por una parte porque si se cierra la ejecución inesperadamente puedes perder todos los datos, y por otra parte, porque complica el control de errores).


05-Jan-2014 16:48
natalia tavora

gracias, voy a leer el curso y a intentarlo de nuevo


05-Jan-2014 17:08
natalia tavora

bien despues de leer el curso, lo pense asi... podrias decirme si esta bien?


Procedure Crear_Usuarios(r_usuarios:Usuarios);
	var
	p:integer;
usuarios,pasword:string;
begin
	
	p:=filesize(f_user);
	gotoxy(25,7); writeln('ingrese nombre de usuario:');
	readln(usuarios);
	gotoxy(25,9); writeln('Ingrese password:');
	gotoxy(25,11); writeln('(numeros y letras, maximo 8 caracteres)');
	readln(Password);
if (p<>0) then
begin
i:=0;
       while ((i<=p) and (usuarios<>r_user.usuarios))do
			read(F_user,r_usuarios);
			if(usuarios<>r_user.usuarios)then
				begin
					p:=p+1;
					seek(f_usuarios,p);
					r_usuarios.usuarios:=usuarios;//como el usuario que ingreso no e
					r_usuarios.password:=password;//
					r_usuarios.puntos:=0;// cero puntos porque es un usuario nuevo
					write(f_user,r_usuarios);
			else
                        writeln('el usuario ya existe, ingrese otro nombre de usuario');
                 end;
end;
	
end;



05-Jan-2014 23:52
Nacho Cabanes (+83)

No, todavía no está bien. Por una parte, no necesitas hacer "seek" en cada pasada, porque cada lectura avanza automáticamente la posición en el fichero.

Por otra parte, como te he dicho antes, no sabes con certeza que no está en el fichero hasta haber recorrido todos los datos, de modo que no puedes guardar hasta ese momento.

Una recomendación: tú misma me has explicado lo que quieres hacer. Con esa idea que tienes en la cabeza, primero escribe comentarios, y luego "rellenas" el hueco entre ellos. A mí no me acaba de gustar eso de que un procedimiento que pide datos de un usuario y comprueba si ya existe, se llame "Crear_Usuarios", pero respetando tu nomenclatura, sería algo parecido a (no lo puedo probar ahora, así que puede contener algún error, pero espero que te ayude a ver la idea):


Procedure Crear_Usuarios();
var
    cantidad, i: integer;
    nombre, password: string;
    encontrado: boolean;
    r_usuarios: Usuarios;
    
begin
    cantidad := filesize(f_user);
    gotoxy(25,7); writeln('ingrese nombre de usuario:');
    readln(nombre);
    gotoxy(25,9); writeln('Ingrese password:');
    gotoxy(25,11); writeln('(numeros y letras, maximo 8 caracteres)');
    readln(Password);
    
    if (cantidad > 0) then { Cuando sí hay datos, busco }
    begin
        i := 1;
        encontrado := false;
        while ((i <= p) and (not encontrado)) do
        begin
            i := i + 1;
            read(f_user,r_usuarios);
            if nombre = r_usuarios.nombre then
                encontrado := true;
        end;
        { Al terminar la búsqueda, ya sé si está o no }
        if encontrado then
            writeln('el usuario ya existe, ingrese otro nombre de usuario');
        else
        begin
            r_usuarios.nombre := nombre;
            r_usuarios.password := password;
            r_usuarios.puntos := 0; { cero puntos porque es un usuario nuevo }
            write(f_user,r_usuarios);
        end;        
    end;    
end;


(Coincido con Luis en que sería más razonable que este procedimiento también fuera el que abriera y cerrara el fichero, en vez de que se haga al principio y al final del cuerpo del programa).


10-Jan-2014 16:35
Invitado (ruben perez)

hola natalia, podria subir el enunciado del ejercicio, para entender en que consiste el juego? gracias


20-Jan-2014 00:43
Invitado (Natalia tavora)

ruben perez no nos dio enunciado, nos dio a elejir entre varios juegos para desarrollar, la unica condicion es que habia que hacer un menu con opciones de configuracion para cambiar el fondo y habia que  aplicar la parte de de archivos para almacenar cosas y que al reiniciar el programa estuviesen guardados... por eso se me ocurrio lo de crear usuarios...
bueno... opte por hacerlo asi... pero me pasa lo mismo que al principio... me saca en la arte que deberia verificar si el usuario existe o no y guardarlo en el registro....


Procedure Crear_Usuarios_part1(var  nombre,password: string);
begin
gotoxy(25,7); writeln('ingrese nombre de usuario:');
    readln(nombre);
    gotoxy(25,9); writeln('Ingrese password:');
    gotoxy(25,11); writeln('(numeros y letras, maximo 8 caracteres)');
    readln(Password);
end;
procedure verifica_usuario(nombre, password: string);
var
    cantidad, i: integer;
    encontrado: boolean;
    r_usuarios: Usuarios;
 
begin
	abrir_archivo();// abro el archivo
    cantidad := filesize(f_user);//me fijo la cantidad de reg almacenados...
    if (cantidad > 0) then //si hay archivos, busco si el usuario existe o no...
    begin
        i := 1;
        encontrado := false;
        repeat
        begin
            i := i + 1;
            read(f_user,r_usuarios);
            if nombre = r_usuarios.id then
                encontrado:= true;
        end;
            if (encontrado=true) then
			begin
				writeln(' el usuario ya existe, intente de nuevo');
				clrscr;
				Crear_Usuarios(nombre,password);
			end;
			
		if (encontrado=false) then //si no existe grabo los datos en el archivo
        begin
            r_usuarios.id := nombre;
            r_usuarios.password := password;
            r_usuarios.puntos := 0; { cero puntos porque es un usuario nuevo }
            write(f_user,r_usuarios);
			
        end;  
		until((i= cantidad) and (not encontrado)); 
    end;   
close(F_user);	
end;



20-Jan-2014 00:56
Nacho Cabanes (+83)

Yo diría que tu rutina de lectura de fichero cuenta un valor por encima de lo que debería, así que no leerá la última ficha. Puede ser más fiable leer con un "while not eof(fichero)".

Aun así, para saber por qué falla puedes usar el depurador de tu entorno de desarrollo, o bien añadir órdenes "WriteLn" que te vayan mostrando en pantalla los puntos por los que pasas y los valores de las variables.

Si debes crear un juego y debe usar ficheros, puede ser más sencillo leer y guardar una tabla de records, en vez de incluir un sistema de control de usuarios.


20-Jan-2014 01:19
Invitado (natalia tavora)

jaja bueno esta bien, me voy a olvidar de los usuarios... .... solo una duda... en un archivo de registros read levanta los datos del archivo y los muestra en un registro vacio? por eso le tengo q pasar como parametro el registro?
y write graba los datos en el archivo?
otra consulta mas como puedo recuperar mi cuenta de este sitio? me olvide el usuario y la contraseña...


20-Jan-2014 20:08
Nacho Cabanes (+83)

Efectivamente, read lee datos del fichero y write guarda en él. Pero si yo fuera tú, emplearía ficheros de texto, en vez de ficheros "con tipo". Te resultará mucho más sencillo. Mira este apartado del curso y el siguiente:

http://aprendeaprogramar.com/mod/resource/view.php?id=154

El usuario y la (nueva) contraseña los has debido recibir por correo. Comprueba tu carpeta de "correo no deseado" a ver si están allí.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)