Jump to content
Carlos Rocha

Gravar no arquivo

Recommended Posts

Carlos Rocha

Pessoal. Boa noite!

Preciso fazer o seguinte:

Tenho um arquivo txt vazio (não tipado),

Tenho um array de strings com 'n' posições. Cada uma com 1 string.

Quero gravar cada posição do array em uma linha no arquivo

Como faço?

O comando write, sobrescreve o conteúdo da linha? Ou dá erro?

Pois assim, em vez de limpar o arquivo, poderei apenas sobrescrever com write linha a linha no arquivo, índice a índice do array.

Será que daria certo?

Edited by carcleo

Share this post


Link to post
Share on other sites
nunopicado

A ideia é simplesmente passar do array para o ficheiro, ou acrescentar?

A maneira mais fácil de fazeres isto será usar uma TStringList, cuja base é a TStrings, que simplisticamente podemos dizer que é um array de strings, como o que já tens.

Imagina que tens um array de strings (v) e queres grava-las num ficheiro ('c:\teste.txt')

Em vez de andares às voltas com os métodos tradicionais, write's e afins, podes gravar directamente um array de strings no ficheiro (sendo que esse array é a TStringList):

var
  v:Array of String;

procedure GravaFicheiro;
var
  lst:TStringList; // Declara-se a TStringList
  i:integer;
begin
  lst:=TStringList.Create; // Cria-se a TStringList

  {A linha seguinte é só se for para acrescentar ao ficheiro. Não deve ser usada se for para escrever no ficheiro só o que está no array }
  lst.LoadFromFile('c:\teste.txt');  // Carrega as linhas que estão no ficheiro para a TStringList

  for i:=0 to Length(v)-1 do  // Percorre-se todo o array
     lst.Add(v[i]); // Adiciona-se cada linha do array à TStringList

  lst.SaveToFile('c:\teste.txt');  // Grava-se o conteúdo da TStringList no ficheiro

  lst.Free; // Liberta a memória ocupada pela TStringList
end;

Idealmente, poderás até substituir o teu array de strings por uma TStringList completa.

Assim, na hora de gravar, basta-te usar o SaveToFile, pois os dados já lá estão.

Edited by nunopicado

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
Carlos Rocha

Na verdade eu até já criei uma procedure.

Nesta procedure, estou a passar como parametro, a variavel arq que é um TextFile.

mas na hora de gravar na linha o pascal (Lazarus) diz que não pode gravar nesse tipo de arquivo.

Veja:

procedure populaNovoArquivo(matriz: array of string; valor: string;  novaLinha: string; var arq: TextFile);
var
 i:integer;
 Parte: TStringList;
 contador: integer;
 linha : string='';
begin
 for i:=low(matriz) to High(matriz) do
 begin
  Parte := TStringList.Create;   Parte.Clear;
  ExtractStrings(['|'],[], PChar(linha), Parte);
  if Parte[0]=valor then
  begin
	matriz[i]:=novaLinha;
  end;
 end;

contador:=0;
while not EOF(arq) do
begin
  writeLn(matriz[contador],arq);
  inc(contador);
end;
end;

Essa variavel matriz, é uma array com todas as linhas que devem ser gravadas no arquivo.

No caso para usar string list eu deveria carregar o array para a string list.

Mas como?

Edited by carcleo

Share this post


Link to post
Share on other sites
nunopicado

Bem, para começar, estás a misturar dois sistemas de manuseio de arquivos, e a falhar em ambos.

Para usar o Writeln, tens de ter ter o arquivo atribuido (AssignFile), pronto a escrever (Reset ou Rewrite) e tem de estar a variável do arquivo antes da string a gravar.

Para usar a TStringList, o método é o que eu descrevi, e não o que puseste.

Estás a cria-la, ok, correcto.

Estás a limpá-la, não era necessário porque foi acabada de criar, mas tudo bem, não estorva.

O ExtractStrings neste caso, não faz sentido usar. Era útil se tivesses todo o conteúdo a gravar numa única string, mas tu tens é num array.

Para o usares, tinhas de percorrer o teu array, somando cada linha ao valor de uma variável string, separando-as por um delimitador, que depois usarias no ExtractStrings. Ora, se é para percorrer o array, vai-se adicionando logo cada linha à TStringList.

Por fim, Aquele While EOF não faz sentido. Estás a escrever, e não a ler. A ler é que precisas saber se o ficheiro chegou ao fim, a escrever vais simplesmente adicionando.

Além de que, uma vez a TStringList preenchida, basta usar o método SaveToFile e ele grava logo, sem mais chatices.

No caso para usar string list eu deveria carregar o array para a string list.

Mas como?

Já pus em cima como deves fazer isto...


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
Carlos Rocha

O que estou a fazer é o seguinte:

Tenho um arquivo de texto (não tipado).

Suas linhas são do tipo:

A|B|C|D

leio ele com Assign e procuro em suas linhas o parâmetro A ou B e comparo com o conteúdo (nome de uma pessoa) de um tEdit.text

Se encontrado, deveremos permitir a alteração desse nome.

Então pensei: basta jogar para um array todas as linhas do arquivo e ler linha a linha do array. e alterar no array.

Após isso, arranjar uma forma de voltar o array corrigido para dentro do arquivo,.

É por aí mesmo?

Share this post


Link to post
Share on other sites
nunopicado

Agora não percebi.

As linhas no arquivo são separadas pelo pipe (|)?

Ou cada registo é uma linha?


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
Carlos Rocha

esse é o arquivo txt:

Carlos|78285020606|2100,32|43

Cleonice|00572596669|1000,00|39

É só teste

O arquivo tem apenas 2 linhas por enquanto

Se existisse:

lst.LoadFromArray(meuArray);

Edited by carcleo

Share this post


Link to post
Share on other sites
nunopicado

Esses campos são familiares...

Isso é o que tens no ficheiro. E no teu array de strings, guardas as strings também nesse formato?


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
Carlos Rocha

sim.

Cada indice do array é uma linha.

somos brasileiros

Se existisse:

lst.LoadFromArray(meuArray);

Array(

0->Carlos|78285020606|2100,32|43

1->Cleonice|00572596669|1000,00|39

)

Edited by carcleo

Share this post


Link to post
Share on other sites
nunopicado

Não precisa... Vê no meu primeiro post:

  for i:=0 to Length(v)-1 do  // Percorre-se todo o array
     lst.Add(v[i]); // Adiciona-se cada linha do array à TStringList

Estas duas linhas de código passam todo o conteúdo do array para dentro da StringList.

Depois basta o SaveToFile para gravar no ficheiro.


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
Carlos Rocha

Assim?

procedure populaNovoArquivo(matriz: array of string; valor: string;  novaLinha: string; var arq: TextFile);
var
 i:integer;
 Parte: TStringList;
 contador: integer;
 linha : string='';
 lst:TStringList; // Declara-se a TStringList
 j:integer;
begin

 for i:=low(matriz) to High(matriz) do
 begin
  Parte := TStringList.Create;   Parte.Clear;
  ExtractStrings(['|'],[], PChar(linha), Parte);
  if Parte[0]=valor then
  begin
	matriz[i]:=novaLinha;
  end;
 end;
parte.free;

 lst:=TStringList.Create; // Cria-se a TStringList
 for j:=0 to Length(matriz)-1 do  // Percorre-se todo o array
   lst.Add(matriz[j]); // Adici
  lst.SaveToFile(arq);  // Grava-se o conteúdo da TStringList no ficheiro

  lst.Free; // Liberta a memória ocupada pela TStringList
end;						  

Mas não precisa limpar o arquvo antes de gravar?

Edited by carcleo

Share this post


Link to post
Share on other sites
nunopicado

Não.

O primeiro FOR não faz falta.

Se no array já tens as strings no formato que é para gravar, só precisas passar do array para a TStringList e depois gravar, ou seja, a última parte do teu procedimento.


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
Carlos Rocha

Não, não.

O array matriz passado por parâmetro contem as linhas do arquivo.

A partir desse array, procuro pelo parâmetro 'valor'.

Se encontrar valor na primeira parte de algum índice do array, esse índice todo será mudado para o conteúdo do parâmetro novoLinha. que é a linha já alterada.

Após isso, terei uma array matriz correto para guardar no arquivo

Share this post


Link to post
Share on other sites
nunopicado

ok, tenta então esse código para ver se dá o que pretendes.

Alguma dúvida, avisa.


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
Carlos Rocha

Que erro tem no cabeçalho dessa procudure?

procedure populaNovoArquivo(var matriz: array of string; valor, novaLinha, arq: string);
var
 i,j :integer;
 Parte, lst: TStringList;
 linha : string='';
begin
 for i:=low(matriz) to High(matriz) do
 begin
  Parte := TStringList.Create;   Parte.Clear;
  ExtractStrings(['|'],[], PChar(linha), Parte);
  if Parte[0]=valor then
  begin
	matriz[i]:=novaLinha;
  end;
 end;
 parte.free;

 lst:=TStringList.Create; // Cria-se a TStringList
 for j:=0 to Length(matriz)-1 do  // Percorre-se todo o array
   lst.Add(matriz[j]); // Adici
  lst.SaveToFile(arq);  // Grava-se o conteúdo da TStringList no ficheiro

  lst.Free; // Liberta a memória ocupada pela TStringList
end;

principal.pas(23,15) Error: Forward declaration not solved "TfrmPrincipal.populaNovoArquivo(var Open Array Of AnsiString,AnsiString,AnsiString,AnsiString);"

É o que o compilador disse

Já achei, basta adicionar o TfrmPrincipal. antes da procedure

Edited by carcleo

Share this post


Link to post
Share on other sites
Carlos Rocha

Veja:

   ls:= TStringList.Create;
   ls.LoadFromFile(nomeArquivo);  

Estou só com uma linha do arquivo ou com todas?

Se estiver com todas, como faço para passar para um array?

Share this post


Link to post
Share on other sites
Carlos Rocha

Esta dando erro na hora de gerar o array;

procedure TfrmPrincipal.btnSalvarClick(Sender: TObject);
var
 linha, funcionario, nomeArquivo: string;
 novaLinha: string;
 arqi: TextFile;
 arquivoDivide: Array of string;
 contador: integer;
begin
 nomeArquivo:=Principal.fileName;

 if (novoNome <> '') or (novoSalario <> '') or (novaIdade <> '') then
 begin
   if novoNome<>'' then
   novaLinha := novoNome + '|' + frmFuncionarios.txtCPF.Text + '|' + frmFuncionarios.txtSalario.Text + '|' + frmFuncionarios.txtIdade.Text;
   if novoSalario<>'' then
   novaLinha := frmFuncionarios.txtNome.Text + '|' + frmFuncionarios.txtCPF.Text + '|' + novoSalario + '|' + frmFuncionarios.txtIdade.Text;
   if novaIdade<>'' then
   novaLinha := frmFuncionarios.txtNome.Text + '|' + frmFuncionarios.txtCPF.Text + '|' + frmFuncionarios.txtSalario.Text + '|' + novaIdade;

   showMessage(novaLinha);
   {============================================}
   AssignFile(arqi, nomeArquivo);
   rewrite(arqi);
   funcionario := frmFuncionarios.txtNome.Text;

   contador:=0;
   while not EOF(arqi) do
   begin
     ReadLn(arqi, linha);
     SetLength(arquivoDivide, contador);
     arquivoDivide[contador]:=linha;
     contador:=contador+1;
   end;
   populaNovoArquivo(arquivoDivide, funcionario, novaLinha, nomeArquivo);

   CloseFile(arqi);

   btnSalvar.Enabled := false;
   {============================================}

 end;
 btnSalvar.Enabled := True;
end;                                          

É na forma de abrir o arquivo.

Ta dificil viu!

Share this post


Link to post
Share on other sites
Carlos Rocha

2 problemas finais aqui;

procedure TfrmPrincipal.PopulaNovoArquivo(var matriz: array of string;
 valor, novaLinha, arq: string);
var
 i, j: integer;
 Parte, lst: TStringList;
 linha: string = '';
begin
 Parte := TStringList.Create;
 lst := TStringList.Create;

 for i := low(matriz) to High(matriz) do
 begin
Parte.Add(matriz[i]);
ExtractStrings(['|'], [], PChar(linha), Parte);
if Parte[0] = valor then
begin
  matriz[i] := novaLinha;
  showmessage(matriz[i]);
  exit;
end;
 end;
 Parte.Free;

 for j := low(matriz) to High(matriz) do
 begin
lst.Add(matriz[j]);
 end;
 lst.SaveToFile(arq);
 lst.Free;
end;	  

Nessa parte:

...

if Parte[0] = valor then
begin
  matriz[i] := novaLinha;
  showmessage(matriz[i]);
  exit;
end;													  ....

O array matriz antes de passar pelo if Parte[0[, esta com os valores normais.

Porem, pos passar pelo if Parte, todos os indices do array estão do mesmo valor.

Mas, eles não são iguais.

Nota: matriz é diferente de novaLinha.

E, aqui;

for j := low(matriz) to High(matriz) do
 begin
lst.Add(matriz[j]);
 end;
 lst.SaveToFile(arq);
 lst.Free;

Esta dando acesso negado ao arquivo.

Qual será o problema?

Edited by carcleo

Share this post


Link to post
Share on other sites
Carlos Rocha

Achei. O erro estava em outro formulário.

Estava abrindo o arquivo mas não chagava a fechar ele. Então, não tinha ´permissão de escrita.

procedure TfrmPesquisa.btnProcurarClick(Sender: TObject);
var
 linha, funcionario: string;
 Parte: TStringList;
 arq: TextFile;
begin
   AssignFile ( arq, Principal.fileName );
   reset ( arq );
   funcionario:=txtNome.text;
   while not Eof ( arq ) do
   begin
     ReadLn ( arq, linha );
     Parte := TStringList.Create;
     Parte.Clear;
     ExtractStrings(['|'],[], PChar(linha), Parte);
     if (Parte[0]=funcionario) or (Parte[1]=funcionario) then
     begin
       nome:=Parte[0];
       CPF:=Parte[1];
       salario:=Parte[2];
       idade:=Parte[3];
        CloseFile (arq);
        frmPesquisa.Hide();
        frmFuncionarios.show();
        Parte.Free;
        abort;
     end;
   end;
   ShowMessage('Nenhum resultado para sua Pesquisa!');
   CloseFile (arq);
end;

eu preciso arranjar uma forma de sair dessa while sem abortar a operaçao de fora a chegar no closeFile (arq) lá embaixo

Edited by thoga31
GeSHi

Share this post


Link to post
Share on other sites
Gilson Nunes

nesse caso o uso do StringList simplifica td o trabalho.

carrega.

localiza;

altera;

salva;

o desse ultipost seria:

function IndexOfFunc(aList : TStrings; const aFunc : String) : Integer;
var
 s : String;
begin
 for Result := 0 to aList.Count - 1 do
 begin
   s := aList[Result];
   if Copy(s, 1, Pos('|', s)) = aFunc then
     Exit;
 end;
 Result := -1;
end;
function Procurar(const aFileName : TFilename; const aFuncionario : String; out aResult : String) : Boolean;
var
 vList : TStringList;
 i : Integer;
begin
 vList := TStringList.Create;
 try
   vList.LoadFromFile(aFileName);
   i := IndexOfFunc(vList, aFuncionario);
   if i >= 0 then
   begin
     aResult := vList[i];
     Result := True;
   end
   else
     Result := False;
 finally
   vList.Free;
 end;
end;
procedure TfrmPesquisa.btnProcurarClick(Sender : TObject);
var
 s : String;
 Parte : TStrings;
begin
 if not Procurar(Principal.fileName, txtNome.text, s) then
   ShowMessage('Nenhum resultado para sua Pesquisa!')
 else
 begin
   Parte := TStringList.Create;
   try
     ExtractStrings(['|'], [], PChar(linha), Parte);
     if Parte.Count > 3 then //e se?
     begin
       nome := Parte[0];
       CPF := Parte[1];
       salario := Parte[2];
       idade := Parte[3];
       frmPesquisa.Hide();
       frmFuncionarios.Show();
     end;
   finally
     Parte.Free;
   end;
 end;
end;

Edited by thoga31
GeSHi

Share this post


Link to post
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

×
×
  • 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.