Carlos Rocha Posted October 17, 2012 at 12:32 PM Report #479479 Posted October 17, 2012 at 12:32 PM Olá pessoal. Criei esse tópico em separado por se tratar de um tema específico No trabalho da faculdade, foi pedido para que eu faça ordenação dentro do arquivo tipado. Estou trabalhando em arquivo do tipo file of real. Que guarda uma Matriz Real. Criei uma funçao para ordenar no arquivo mas até mesmo na exibiçao do tamanho do arquivo da erro. Onde será que esta o erro? Segue a função que criei: Obs.: A ordenaçao tem que ser no arquivo. Jogar para um array e ordenar não pode. //ordena_em_arquivo procedure ordena_em_arquivo(var arq:ArqFlutuante); var aux, valor_j, valor_i:real; i, j: integer; begin reset(arq); for i:=0 to filesize(arq)-1 do begin for j:=i+1 to filesize(arq) do begin seek (arq, i); read (arq, valor_i); seek (arq, j); read (arq, valor_j); if valor_j < valor_i then begin aux:=valor_j; valor_j:=valor_i; valor_i:=aux; seek(arq,i); write(arq,valor_i); seek(arq,j); write(arq,valor_j); end; end; end; close(arq); end; Segue o código todo para melhor verificaçao program Questao2; uses crt, sysutils; Type ArqFlutuante = File of real; MatrizReal = array[0..10] of real; var arquivo: ArqFlutuante; valores: MatrizReal; nome: string; quantidade, TermoProcura:integer; valor_ini,valor_fim:real; //Popula Arquivo procedure popula(var arq:ArqFlutuante; qtd:integer; val_ini:real; val_fim:real); var valor_popula: real; ini: integer; begin reset(arquivo); // colocando o ponteiro no inicio do arquivo; //popula o arquivo for ini:=1 to qtd do begin valor_popula:= val_ini + ((val_fim - val_ini) * random); write(arq, valor_popula); end; close(arq); end; //Media function media(var arq:ArqFlutuante; qtd:integer):real; var valor_total: real; linha: real; begin reset(arquivo); // colocando o ponteiro no inicio do arquivo; valor_total:=0.00; while not eof(arq) do begin read(arq,linha); valor_total:=valor_total+linha; end; media:=valor_total/qtd; close(arq); end; //Exibe o arquivo procedure mostra_arquivo (var arq: ArqFlutuante); var linha: real; begin reset(arq); while not eof(arq) do begin read(arq, linha); writeLn(linha:2:2); end; close(arq); end; //ordena_em_arquivo procedure ordena_em_arquivo(var arq:ArqFlutuante); var aux, valor_j, valor_i:real; i, j: integer; begin reset(arq); for i:=0 to filesize(arq)-1 do begin for j:=i+1 to filesize(arq) do begin seek (arq, i); read (arq, valor_i); seek (arq, j); read (arq, valor_j); if valor_j < valor_i then begin aux:=valor_j; valor_j:=valor_i; valor_i:=aux; seek(arq,i); write(arq,valor_i); seek(arq,j); write(arq,valor_j); end; end; end; close(arq); end; //Cria o array Valores para posterior verificação do terceiro maior elemento function array_arquivo(var arq:ArqFlutuante):MatrizReal; var i:integer; linha: real; Array_de_arquivo:MatrizReal; begin reset(arq); i:=0; while not eof(arq) do begin read(arq, linha); Array_de_arquivo[i]:=linha; inc(i); end; array_arquivo:=Array_de_arquivo; close(arq); end; //mostra array procedure mostra_array(Matriz:MatrizReal); var i:integer; begin writeLn('Matriz valores Ordenada pelo arquivo:'); for i:=Low(Matriz) to High(Matriz) do writeLn(Matriz[i]:2:2); end; //Identifica o terceiro maior function encontra_valor(Matriz:MatrizReal; procura:Integer):Real; var contador,i: integer; begin if High(Matriz)>=procura then begin contador:=1; for i:=High(Matriz) downto Low(Matriz) do begin if Matriz[i]<>Matriz[i-1] then inc(contador); if contador=procura then begin encontra_valor:=Matriz[i-1]; break; end; end; end; end; BEGIN randomize; // Optimiza random para que não haja repetição. // Pedindo dados ao usuario: writeLn('Atencao:'); writeLn('Serao pedidos em sequencia: '); writeLn('Um nome para criarmos um arquivo,'); writeLn('uma quantidade de numeros para inserirmos nesse arquivo e '); writeLn('a faixa (valor inicial, valor final) dos numeros a serem inseridos nesse arquivo.'); writeLn; writeLn('Entao:'); writeLn; writeLn('Digite um nome para o nosso arquivo:'); read(nome); nome:= nome+'.txt'; writeLn('Digite agora uma quantidade de numeros para inserirmos nesse arquivo:'); read(quantidade); //SetLength(valores, quantidade-1); writeLn('Digite agora a faixa (valor inicial e valor final) dos numeros a serem inseridos nesse arquivo.'); writeLn('Exemplo: 1.34 e 9.59'); readLn(valor_ini, valor_fim); writeLn; assign(arquivo, nome); //atrelando variavel ao arquivo: rewrite(arquivo); //criando o arquivo (que não existe): //Populando o arquivo popula(arquivo,quantidade,valor_ini,valor_fim); //mostra o arquivo desordenado writeLn('Exibindo o arquivo desordenado'); mostra_arquivo(arquivo); //exibe o arquivo //Faz a ordenação do array valores para posterior alteração do arquivo para os valores ja ordenados ordena_em_arquivo(arquivo); //mostra o arquivo Ordenado writeLn('Exibindo o arquivo Ordenado'); mostra_arquivo(arquivo); //exibe o arquivo //Cria o array Valores para posterior verificação do terceiro maior elemento valores:=array_arquivo(arquivo); //Verifica criaçao do array Valores mostra_array(valores); //Exibindo a media que veio quando da chamada à procedure popula writeLn; // Espaço da exibiçao Ordenada. writeLn('Exibindo a media'); writeLn('A media e: ',media(arquivo,quantidade):2:2); writeLn; // Espaço da exibiçao da media. writeLn('Exibindo o terceiro termo caso ele exista'); TermoProcura:=3; if encontra_valor(valores, TermoProcura)>0.00 then write ('O ',TermoProcura,'º maior numero e: ',encontra_valor(valores, TermoProcura):2:2) else write ('O arquivo nao possui um terceiro termo'); readkey; END.
nunopicado Posted October 17, 2012 at 12:47 PM Report #479482 Posted October 17, 2012 at 12:47 PM (edited) Os índices dos ficheiros em pascal têm base 0, ou seja, começam em 0 e terminam em FileSize(Arq) - 1. Ou seja, o teu primeiro comando FOR começa em 0 (está bem), mas o segundo FOR termina em FileSize(Arq) (um registo que ainda não existe) e é aí que ele vai dar erro. O teu segundo FOR precisa portanto de terminar em FileSize(Arq) - 1, o que obriga a que o primeiro FOR termine em FileSize(Arq) - 2. . . . for i:=0 to filesize(arq)-2 do begin for j:=i+1 to filesize(arq)-1 do begin . . . Edited October 17, 2012 at 12:48 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 17, 2012 at 01:41 PM Author Report #479487 Posted October 17, 2012 at 01:41 PM Corrigida essa parte, não sei porque, mas essa ordenaçao esta me retornando 1 numeros reais. Mesmo que mande entrar com 5 me manda 11.
nunopicado Posted October 17, 2012 at 01:48 PM Report #479488 Posted October 17, 2012 at 01:48 PM Experimenta, quando estás a inserir os valores no arquivo, antes do write(arq, valor_popula); mete seek(Arq,FileSize(Arq)); Assim ele irá escrever na primeira posição disponível do arquivo. "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 17, 2012 at 01:50 PM Author Report #479489 Posted October 17, 2012 at 01:50 PM (edited) A ordenaçao agora deu certo mas acho que achei outro erro: Tem algum aqui erro? //Cria o array Valores para posterior verificação do terceiro maior elemento function array_arquivo(var arq:ArqFlutuante):MatrizReal; var i:integer; linha: real; Array_de_arquivo:MatrizReal; begin reset(arq); i:=0; while not eof(arq) do begin read(arq, linha); Array_de_arquivo[i]:=linha; inc(i); end; array_arquivo:=Array_de_arquivo; close(arq); end; Edited October 17, 2012 at 01:53 PM by carcleo
nunopicado Posted October 17, 2012 at 02:05 PM Report #479494 Posted October 17, 2012 at 02:05 PM (edited) Penso que o erro será estares dependente do read para gerir a posição do arquivo a ser lido. Eu pelo menos nunca gostei desse risco. Experimenta o seguinte. Em vez do WHILE, mete um ciclo FOR, a começar em 0 e a terminar em FileSize(Arq)-1. Depois, antes do read(arq, linha); mete também o Seek(Arq,i); Assim ele irá sempre ler da posição correcta, sem perigo de se perder. Tenta a ver se isso resolve! Edited October 17, 2012 at 02:06 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 17, 2012 at 02:10 PM Author Report #479497 Posted October 17, 2012 at 02:10 PM Não é não. Achei o erro. É o seguinte, essa funçao devolve um array do tipo MatrizReal que é array[0..10] então, ele fica criando um array com 11 posições. Na verdade, precisaria usar array dinamico. Mas, quando uso array dinamico, o freepascal 2.6.0 da erro 217. Manipulação errada de real. Talves seja por causa que eu estou usando winmdows. Voce testa ai pra mim pra ver se dá erro fazendo favor? Eis o codigo corrigido: program Questao2; uses crt, sysutils; Type ArqFlutuante = File of real; MatrizReal = array of real; //MatrizReal = array[0..10] of real; var arquivo: ArqFlutuante; valores: MatrizReal; nome: string; quantidade, TermoProcura:integer; valor_ini,valor_fim:real; //Popula Arquivo procedure popula(var arq:ArqFlutuante; qtd:integer; val_ini:real; val_fim:real); var valor_popula: real; ini: integer; begin reset(arq); // colocando o ponteiro no inicio do arquivo; //popula o arquivo for ini:=1 to qtd do begin valor_popula:= val_ini + ((val_fim - val_ini) * random); write(arq, valor_popula); end; close(arq); end; //Media function media(var arq:ArqFlutuante; qtd:integer):real; var valor_total: real; linha: real; begin reset(arquivo); // colocando o ponteiro no inicio do arquivo; valor_total:=0.00; while not eof(arq) do begin read(arq,linha); valor_total:=valor_total+linha; end; media:=valor_total/qtd; close(arq); end; //Exibe o arquivo procedure mostra_arquivo (var arq: ArqFlutuante); var linha: real; begin reset(arq); while not eof(arq) do begin read(arq, linha); writeLn(linha:2:2); end; close(arq); end; //mostra array procedure mostra_array(Matriz:MatrizReal); var i:integer; begin writeLn('Matriz valores Ordenada pelo arquivo:'); for i:=Low(Matriz) to High(Matriz) do writeLn(Matriz[i]:2:2); end; //ordena_em_arquivo procedure ordena_em_arquivo(var arq:ArqFlutuante); var aux, valor_j, valor_i:real; i, j: integer; begin reset(arq); for i:=0 to filesize(arq)-1 do begin for j:=i+1 to filesize(arq)-1 do begin seek (arq, i); read (arq, valor_i); seek (arq, j); read (arq, valor_j); if valor_j < valor_i then begin aux:=valor_j; valor_j:=valor_i; valor_i:=aux; seek(arq,i); write(arq,valor_i); seek(arq,j); write(arq,valor_j); end; end; end; close(arq); end; //Cria o array Valores para posterior verificação do terceiro maior elemento function array_arquivo(var arq:ArqFlutuante):MatrizReal; var i:integer; linha: real; Array_de_arquivo:MatrizReal; begin reset(arq); i:=0; while not eof(arq) do begin read(arq, linha); Array_de_arquivo[i]:=linha; inc(i); end; array_arquivo:=Array_de_arquivo; close(arq); end; //Identifica o terceiro maior function encontra_valor(Matriz:MatrizReal; procura:Integer):Real; var contador,i: integer; begin if High(Matriz)>=procura then begin contador:=1; for i:=High(Matriz) downto Low(Matriz) do begin if Matriz[i]<>Matriz[i-1] then inc(contador); if contador=procura then begin encontra_valor:=Matriz[i-1]; break; end; end; end; end; BEGIN randomize; // Optimiza random para que não haja repetição. // Pedindo dados ao usuario: writeLn('Atencao:'); writeLn('Serao pedidos em sequencia: '); writeLn('Um nome para criarmos um arquivo,'); writeLn('uma quantidade de numeros para inserirmos nesse arquivo e '); writeLn('a faixa (valor inicial, valor final) dos numeros a serem inseridos nesse arquivo.'); writeLn; writeLn('Entao:'); writeLn; writeLn('Digite um nome para o nosso arquivo:'); read(nome); nome:= nome+'.txt'; writeLn('Digite agora uma quantidade de numeros para inserirmos nesse arquivo:'); read(quantidade); SetLength(valores, quantidade-1); writeLn('Digite agora a faixa (valor inicial e valor final) dos numeros a serem inseridos nesse arquivo.'); writeLn('Exemplo: 1.34 e 9.59'); readLn(valor_ini, valor_fim); writeLn; assign(arquivo, nome); //atrelando variavel ao arquivo: rewrite(arquivo); //criando o arquivo (que não existe): //Populando o arquivo popula(arquivo,quantidade,valor_ini,valor_fim); //mostra o arquivo desordenado writeLn('Exibindo o arquivo desordenado'); mostra_arquivo(arquivo); //exibe o arquivo //Faz a ordenação do array valores para posterior alteração do arquivo para os valores ja ordenados ordena_em_arquivo(arquivo); //mostra o arquivo Ordenado writeLn('Exibindo o arquivo Ordenado'); mostra_arquivo(arquivo); //exibe o arquivo //Cria o array Valores para posterior verificação do terceiro maior elemento valores:=array_arquivo(arquivo); //Verifica criaçao do array Valores mostra_array(valores); //Exibindo a media que veio quando da chamada à procedure popula writeLn; // Espaço da exibiçao Ordenada. writeLn('Exibindo a media'); writeLn('A media e: ',media(arquivo,quantidade):2:2); writeLn; // Espaço da exibiçao da media. writeLn('Exibindo o terceiro termo caso ele exista'); TermoProcura:=3; if encontra_valor(valores, TermoProcura)>0.00 then write ('O ',TermoProcura,'º maior numero e: ',encontra_valor(valores, TermoProcura):2:2) else write ('O arquivo nao possui um terceiro termo'); readkey; END.
nunopicado Posted October 17, 2012 at 02:12 PM Report #479498 Posted October 17, 2012 at 02:12 PM Eu também uso o Windows, mas não tenho o FPC instalado aqui. Experimenta colocar um array de 0..100. "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 17, 2012 at 02:15 PM Author Report #479499 Posted October 17, 2012 at 02:15 PM Não posso pois dependo do campo quantidade para dizer quantos indices exatos terá o array para calculos do terceiro maior valor
ARSaraiva Posted October 26, 2012 at 09:04 PM Report #480620 Posted October 26, 2012 at 09:04 PM Caro carcleo, desconfio que fazemos a mesma faculdade, pois minha AD2 é exatamente estas questões. Se possível entre em contato pelo email andresaraiva@id.uff.br, pois consegui a solução da questão 2 e estou com problemas na questão 3.
djthyrax Posted October 27, 2012 at 08:15 PM Report #480718 Posted October 27, 2012 at 08:15 PM Porque não partilhar por aqui? Assim ficamos todos a saber a solução. 🙂 Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum!
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