Jump to content

Recommended Posts

Posted

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.
Posted (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 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.

Posted

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.

Posted (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 by carcleo
Posted (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 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.

Posted

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.
Posted

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.

  • 2 weeks later...
Posted

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.

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.