Carlos Rocha Posted October 9, 2013 at 08:47 PM Report #528253 Posted October 9, 2013 at 08:47 PM (edited) 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 October 9, 2013 at 08:52 PM by carcleo
nunopicado Posted October 9, 2013 at 09:17 PM Report #528260 Posted October 9, 2013 at 09:17 PM (edited) 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 October 9, 2013 at 09:18 PM 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.
Carlos Rocha Posted October 9, 2013 at 09:26 PM Author Report #528261 Posted October 9, 2013 at 09:26 PM (edited) 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 October 9, 2013 at 09:36 PM by carcleo
nunopicado Posted October 9, 2013 at 09:39 PM Report #528264 Posted October 9, 2013 at 09:39 PM 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.
Carlos Rocha Posted October 9, 2013 at 09:53 PM Author Report #528270 Posted October 9, 2013 at 09:53 PM 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?
nunopicado Posted October 9, 2013 at 09:55 PM Report #528271 Posted October 9, 2013 at 09:55 PM 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.
Carlos Rocha Posted October 9, 2013 at 10:03 PM Author Report #528272 Posted October 9, 2013 at 10:03 PM (edited) 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 October 9, 2013 at 10:05 PM by carcleo
nunopicado Posted October 9, 2013 at 10:05 PM Report #528273 Posted October 9, 2013 at 10:05 PM 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.
Carlos Rocha Posted October 9, 2013 at 10:06 PM Author Report #528274 Posted October 9, 2013 at 10:06 PM (edited) 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 October 9, 2013 at 10:08 PM by carcleo
nunopicado Posted October 9, 2013 at 10:08 PM Report #528275 Posted October 9, 2013 at 10:08 PM 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.
Carlos Rocha Posted October 9, 2013 at 10:15 PM Author Report #528277 Posted October 9, 2013 at 10:15 PM (edited) 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 October 9, 2013 at 10:18 PM by carcleo
nunopicado Posted October 9, 2013 at 10:17 PM Report #528278 Posted October 9, 2013 at 10:17 PM 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.
Carlos Rocha Posted October 9, 2013 at 10:30 PM Author Report #528281 Posted October 9, 2013 at 10:30 PM 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
nunopicado Posted October 9, 2013 at 10:31 PM Report #528283 Posted October 9, 2013 at 10:31 PM 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.
Carlos Rocha Posted October 9, 2013 at 11:00 PM Author Report #528287 Posted October 9, 2013 at 11:00 PM (edited) 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 October 9, 2013 at 10:52 PM by carcleo
Carlos Rocha Posted October 9, 2013 at 11:34 PM Author Report #528292 Posted October 9, 2013 at 11:34 PM 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?
Carlos Rocha Posted October 10, 2013 at 12:11 AM Author Report #528296 Posted October 10, 2013 at 12:11 AM 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!
Carlos Rocha Posted October 10, 2013 at 12:55 AM Author Report #528299 Posted October 10, 2013 at 12:55 AM (edited) 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 October 10, 2013 at 01:58 AM by carcleo
Carlos Rocha Posted October 10, 2013 at 01:03 PM Author Report #528344 Posted October 10, 2013 at 01:03 PM (edited) 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 October 10, 2013 at 05:05 PM by thoga31 GeSHi
Gilson Nunes Posted October 10, 2013 at 10:48 PM Report #528432 Posted October 10, 2013 at 10:48 PM (edited) 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 October 11, 2013 at 03:11 PM by thoga31 GeSHi
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now