Jump to content

Como gravar um ficheiros de dados em pascal?


dicas3d
 Share

Recommended Posts

Preciso de guardar os dados de um login num ficheiro.Estava a pensar em usar um registo chamado login e um vector unidimensional chamado contas do tipo login.

Como faço para guardar/ler os dados no ficheiro?

Sei que algo assim para um caso e para o outro.

type login = RECORD
Nome : string;
Password : string;
var c : file of login;
contas : array[0..20] of login;
begin
assign(c,'C:\contas.sgs');
close(c);

end;

Expliquem-me agora melhor como o fazer.

Abraços

dicas3d

Link to comment
Share on other sites

Boas, dicas3d ?

Vou-te dar uma breve explicação de como se escreve em ficheiros.

Para arrancar o ficheiro, pelo que me parece já sabes como o fazer, bem como para o encerrar. Contudo, falta-te dar ordem ao programa para ou reescrevê-lo ou reiniciá-lo. Esta última operação só é válida no caso de o ficheiro já existir.

No teu caso, tens de escrever no ficheiro o que se passa no login:

assign(c,'C:\contas.sgs');
rewrite(c);  // dá ordem para apagar todo o conteúdo do ficheiro caso já exista, e começar a escrever nele quer exista quer tenha acabado de ser criado

writeln(c,'Exemplo de linha de texto');  // escreve no ficheiro

Para o caso de o ficheiro já existir, e caso queiras ler o seu conteúdo:

{var linha:array[1..100] of string;
     i:integer;}

assign(c,'C:\contas.sgs');
reset(c);  // como o ficheiro já existe, acede a este e NÃO apaga o conteúdo.
i:=0;
while NOT eof(c) do begin  // enquanto não for o fim do ficheiro, vai lendo linha a linha
      i:=i+1;
      readln(c,linha[i]);  // ler a linha e gravar o seu conteúdo em linha[i]
end;

Alguma dúvida pergunta. Para a dúvida que colocaste é o melhor que poderei explicar.

Cumpz. 😉

Knowledge is free!

Link to comment
Share on other sites

E u já tenho este codigo posto, mas ele não lê o registo todo. Só lê o administrador.

Type login = RECORD
nome : shortstring;
password : shortstring;
end;
var f : file of login;
linha : array[0..1000] of login;
c, nome, pass : shortstring;
i, d : integer;
begin
Assign(f,c);
Reset(f);
i := 0;
while not eof(f) do read(f,linha[system.filepos(f)]);
if linha[i].password = pass then begin
end;
close(f);

Abraços

dicas3d

Link to comment
Share on other sites

Não devias avançar o i dentro do while?

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to comment
Share on other sites

Faz println de cada registo que estás a ler.

Ele pára no primeiro ou no último?

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to comment
Share on other sites

Já lá vão uns anos, não sei se tens de iterar pelo array quando gravas ou se mandas para lá o array de forma directa.

Só estar a ler o nome é que é mais estranho.

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to comment
Share on other sites

Olá,

O código pareceu-me um pouco confuso, por isso reformatei-o e coloquei algumas notas... De qualquer modo, penso que esta é uma solução pouco eficiente para o problema que queres resolver.

Estás a gastar 256x2 = 512 bytes por cada registo.

Pesquisa por exemplo pelo ficheiro /etc/passwd utilizado no linux e outros sistemas operativos... é um ficheiro de texto, mais propriamente um DSV (valores separados por delimitador)... podias ter um ficheiro com registos assim:

nome:password
dicas3d:floobity
pwseo:foobar
pedro-kun:blaghity

É muito mais económico (em menos de um terço do espaço colocas logo 3x mais utilizadores... de certeza que ninguém precisa de 255 caracteres de username e de password). Apenas terias que programar um método de extrair o nome e a password de uma string com um ":" no meio.

Ah! e não guardes as passwords assim em texto plano... aplica-lhes alguma cifra ou assim 🙂

De qualquer modo, aqui fica o teu código reformatado (se puderes mostra também como estavas a fazer para gravar o ficheiro):

type login =  record
  nome: shortstring;
  password: shortstring;
end;

var
  f: file of login;
  linha: array[0..1000] of login;
  c, nome, pass: shortstring;
  i, d : integer;

begin
  // assegurar que c contém um ficheiro válido
  assign(f,c);
  reset(f);
  i := 0;
  while not eof(f) do
  begin
    read(f,linha[i]); // se estás a ler em sequência não precisas do system.filepos porque o seu valor é i, penso eu
    i := i + 1; // falta-te isto aqui
    if linha[i].password = pass then // esta condição é para ficar dentro do ciclo?
    begin
      // coisas aqui
    end;
  end; // também está em falta?
  close(f);
end.

P.S.: o meu pascal está enferrujadíssimo

Link to comment
Share on other sites

Já tenha a parte da leitura a funcionar OK.

conta := false;
c := envstr(2) + '\contas.sgs';
delete(c,1,4);
if length(edit1.Caption) > 0 then begin
Assign(loginfile,c);
Reset(loginfile);
t := filesize(loginfile) + 1;
i := 0;
for i := 1 to t do begin
Seek(loginfile,i);
while not eof(loginfile) do read(loginfile,tmplogin);
if (tmplogin.nome = Edit1.Text) and (tmplogin.password = Edit2.Text) then begin
Conta := true;
p := tmplogin;
end;
contasarray[i] := tmplogin;
end;
end;
Close(loginfile);

Eu uso um registo que é para armazenar tmbem os tipos de contas numa registo boolean. Só há 2 tipos de conta.

Eu tenho mesmo de usar system porque estou a usar o Lazarus como tal para desambiguar de uma função homónima do delphi tenho de introduzir system. Eu é que adapto o código para ser mais familiar a quem apenas usa o Pascal em modo linha de comandos.

Agora o meu problema é outro. Na gravação das contas ele não grava mais que 2 ou 3 linhas de registos.

Aqui vai o meu código:

var c, nome, pass : string;
d : integer;
begin
c := envstr(2)+ '\contas.sgs';
Delete(c,1,4);
Assign(loginfile,c);
Rewrite(loginfile);
i := t + 1;
t := i;
contasarray[i].tipo:= rdbAdmin.Checked;
contasarray[i].nome:=edtNome.Text;
contasarray[i].password:=edtPass.Text;
seek(loginfile,i-1);
for t := 1 to i do write(loginfile,contasarray[t]);
close(loginfile);
end;

Quanto aos objecto aqui usados para quem não sabe, considere-mos um registo comum.

Abraços

dicas3d

Link to comment
Share on other sites

Estive a olhar melhor para o teu código de leitura... Experimentaste com registos diferentes e ele leu todos os registos correctamente? Porque fiquei a olhar meio desconfiado para lá.. aquele while dentro do for pareceu-me suspeito.

Quanto à função de escrita, qual é o valor de t? E já agora, não precisas de fazer aquelas brincadeiras todas com o i e o t 🙂

Link to comment
Share on other sites

A variável t é global.  eindica o total de indices de contasarray. Isto é só um procedimento.

E já agora, não precisas de fazer aquelas brincadeiras todas com o i e o t 😄

Explica-me melhor essa sff.

Abraços

dicas3d

Link to comment
Share on other sites

Ah, ok é uma global. Sendo assim, podes fazer o que quiseres... ali, no contexto em que mostraste, parecia um pouco estranho andares a dizer que i era t+1 para depois dizeres que t era i (que é o mesmo que inc(t) e pronto). Mesmo assim, parece estranho

Mesmo assim, relativamente ao teu código de leitura, viste se ele lê os registos bem? quando "imprimes" os registos para o ecrã, todos eles batem certo? (faz sempre testes com registos com dados diferentes).

Outra coisa, na tua função de gravação, se tens contasarray de 0..i, não podes escrever um loop de t = 1 até i porque estás a perder o primeiro registo.

De qualquer modo, volto a dizer que um simples ficheiro de texto era uma solução melhor 🙂

Link to comment
Share on other sites

program tipos;
type tipo = Record
registo1 : (tipo2);
total : (numero);
var var_file_of_type : file of tipo;
vector : array[(min)..(max)] of tipo
begin
assign(var_file_of_type,directorio);
rewrite(var_file_of_type);
(*inicio do código da escrita*)
for i := 1 to 3 do begin
write(var_file_of_type, vector[i]);
vector[i].total := total_indices;
end;
(*fim do código da escrita*)
(*inicio do código da leitura*)
t := total_indices;
reset(var_file_of_type);
for i := 1 to t do begin
seek(var_file_of_type, i-1);
read(var_file_of_type, vector[i]);
end;
close(var_file_of_type);
end;

Eis como imlementar ficheiros com Records. Por agora não sei como determinar o total de linhas do ficheiro. E eis como implementar um sistema de logins em ficheiros de texto.

procedure TfrmConta.btnContaClick(Sender: TObject);
var c, tipo, pass : string;
d : integer;
begin
c := envstr(2)+ '\contas.sgs';
system.Delete(c,1,4);
system.assign(loginfile,c);
system.Rewrite(loginfile);
if rdbAdmin.Checked = true then tipo := ':True' else tipo := ':False';
contasarray[i+1] := edtNome.Text + ':' + edtPass.Text + tipo;
for t := 0 to i + 1 do begin
writeln(loginfile, contasarray[t]);
end;
system.Close(loginfile);
end;

Este é o procedimento da escrita.

procedure TfrmLogin.Button1Click(Sender: TObject);
var d, n : shortstring;
len, t, f : integer;
begin
conta := false;
c := envstr(2) + '\contas.sgs';
delete(c,1,4);
if length(edtNome.Caption) > 0 then begin
system.assign(loginfile,c);
system.Reset(loginfile);
i := 0;
while not eof(loginfile) do begin
readln(loginfile, contasarray[i]);
c := contasarray[i];
n := edtNome.Text +':'+edtPass.Text+':'+'True';
d := edtNome.Text +':'+edtPass.Text+':'+'False';
if n = contasarray[i] then begin
Conta := true;
tipo:=true;
end;
if d = contasarray[i] then begin
Conta := true;
tipo:=false;
end;
i := i + 1;
end;
system.close(loginfile);
end;
if Conta = true then begin
frmPrincipal.Show;
frmLogin.hide;
end;
end; 

Este é o procedimento de leitura.

Abraços

dicas3d

Link to comment
Share on other sites

Eis a implementação correta de ficheiros de dados em Lazarus. A forma é igual, mas tem um truque. É preciso remover "{$H+}"  do topo. Para não dar problemas devem-se ter os tipos numa unit separada, e nesata unit sim remover "{$H+}".

Abraços

dicas3d

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.