Use o botão abaixo para reportar erros ou dar sugestões.

Computação Científica - Um Livro Colaborativo

8.5 Acesso direto e acesso sequencial


Até o momento nós abrimos os arquivos e lemos sequencialmente a partir do início, isto é, fizemos acesso sequencial. Agora, pretendemos ler uma posição do arquivo sem lê-lo desde o início, isto é, pretendemos acessar diretamente um elemento. Os comandos úteis para se posicionarmos ao longo do arquivo são: ftell, que entra um ponteiro para arquivo e retorna a posição e rewind, que entra um arquivo e o posiciona o início.

Exemplo 8.5.1. Reescreva um código que lê o arquivo gerado no exemplo 8.4.4, depois lê o primeiro número novamente.

#include <stdio.h>  
#include <stdlib.h>  
 
int main(void)  
{  
  double v[20],*p=v,first;  
  FILE *arq;  
  int i,ch;  
  long int total;  
  arq=fopen("saida.dat","rb");  
  if (arq==NULL)  
    printf("Não conseguiu abrir o arquivo\n");  
  else  
    {  
    printf("Arquivo aberto com sucesso\n");  
    printf("%ld\n",total=ftell(arq));  
    while ((ch=fread(p,sizeof(double),1,arq))!=0)  
    {  
    p++;  
    }  
    printf("%ld\n",total=ftell(arq));  
    rewind(arq);  
    printf("%ld\n",ftell(arq));  
    fread(&first,sizeof(double),1,arq);  
    printf("%ld\n",ftell(arq));  
    fclose(arq);  
    printf("Arquivo fechado com sucesso\n");  
    }  
  printf("%ld\n",total/=8);  
  for (i=0;i<total;i++) printf("%f\n",v[i]);  
  printf("first=%f\n",first);  
}

A função usada para posicionamento dentro do arquivo é a

int fseek(FILE *arq,long int salto, int origem)

onde

  • FILE é um ponteiro para arquivo.
  • saltoé o número de bytes que desejamos andar (positivo para frente e negativo para trás).
  • origem é o local de onde queremos saltar, podemos assumir os seguintes valores:

      SEEK_SET salto realizado a partir da origem do arquivo.

      SEEK_CUR salto realizado a partir da posição atual.

      SEEK_END salto realizado a partir da fim do arquivo.

Exemplo 8.5.2. Reescreva um código que lê o arquivo gerado no exemplo 8.4.4, depois lê somente os três últimos.

#include <stdio.h>  
#include <stdlib.h>  
 
int main(void)  
{  
  double v[20],*p=v,last[3];  
  FILE *arq;  
  int i,ch;  
  long int total;  
  arq=fopen("saida.dat","rb");  
  if (arq==NULL)  
    printf("Não conseguiu abrir o arquivo\n");  
  else  
    {  
    printf("Arquivo aberto com sucesso\n");  
    printf("%ld\n",total=ftell(arq));  
    while ((ch=fread(p,sizeof(double),1,arq))!=0)  
    {  
    p++;  
    }  
    printf("%ld\n",total=ftell(arq));  
    fseek(arq,-24,SEEK_END);  
    printf("onde estou? %ld\n",ftell(arq));  
    fread(last,sizeof(double),3,arq);  
    fclose(arq);  
    printf("Arquivo fechado com sucesso\n");  
    }  
  printf("%ld\n",total/=8);  
  for (i=0;i<total;i++) printf("%f\n",v[i]);  
  printf("\n");  
  for (i=0;i<3;i++) printf("%f\n",last[i]);  
}

Exemplo 8.5.3. Vamos resolver o exemplo 4.3.1 novamente imprimindo a solução em arquivo. Vamos usar o mesmo código, ampliando apenas as linhas que salvam em arquivo binário.

#include <stdio.h>  
#include <math.h>  
 
#define N 101 /* dimensão do sistema*/  
 
double norma_2(double x[N])  
{  
  int i;  
  double norma2=x[0]*x[0]/(2*(N-1));  
  for (i=1;i<N-1;i++)  
  {  
    norma2+=x[i]*x[i]/(N-1);  
  }  
  norma2+=x[N-1]*x[N-1]/(2*(N-1));  
  return sqrt(norma2);  
}  
void Iteracao(double u_antigo[N],double u_atual[N],double matriz[N][N], double vetor[N])  
{  
  double aux;  
  int i,j;  
  for (i=0;i<N;i++)  
  {  
    aux=0;  
    for (j=0;j<i;j++)  
    aux+=matriz[i][j]*u_antigo[j];  
    for (j=i+1;j<N;j++)  
    aux+=matriz[i][j]*u_antigo[j];  
    u_atual[i]=(vetor[i]-aux)/matriz[i][i];  
  }  
}  
void Jacobi(double tolerancia,double u_atual[N],double vetor[N],double matriz[N][N],double malha[N])  
{  
 
  double u_antigo[N],dif[N];  
  int i,controle=3;  
 
  //chute inicial  
  for (i=0;i<N;i++)u_antigo[i]=0;  
 
  //iteração  
  while (controle)  
  {  
    Iteracao(u_antigo,u_atual,matriz,vetor);  
    for (i=0;i<N;i++) dif[i]=u_atual[i]-u_antigo[i];  
    if (norma_2(dif)<tolerancia) controle--;  
    else controle=3;  
    for (i=0;i<N;i++) u_antigo[i]=u_atual[i];  
  }  
  return;  
}  
 
double solucao_analitica(double x)  
{  
return -25.*(x-1.)*(x-1.)*(x-1.)*(x-1.)/3-25.*x/3+25./3.;  
}  
 
main (void)  
{  
  int i,j;  
  double tolerancia=1e-5,solucao[N],sol_anal[N];  
  double matriz[N][N];  
  double vetor[N],x[N];  
  //malha  
  double h=1./(N-1);  
  for (i=0;i<N;i++)  
    {  
    x[i]=i*h;  
    sol_anal[i]=solucao_analitica(x[i]);  
    }  
  //matriz e vetor  
  for (i=0;i<N;i++) for (j=0;j<N;j++) matriz[i][j]=0;  
  matriz[0][0]=1;  
  vetor[0]=0;  
  for (i=1;i<N-1;i++)  
  {  
    matriz[i][i]=-2;  
    matriz[i][i+1]=1;  
    matriz[i][i-1]=1;  
    vetor[i]=-100*h*h*(x[i]-1)*(x[i]-1);  
  }  
  matriz[N-1][N-1]=1;  
  vetor[N-1]=0;  
 
  Jacobi(tolerancia,solucao,vetor,matriz,x);  
  //erro médio  
  double erro=0;  
  for (i=0;i<N;i++) erro+=fabs(solucao[i]-sol_anal[i]);  
  erro/=N;  
  printf("erro médio = %f\n",erro);  
  for (i=0;i<N;i++)     printf("u_%d=%f, u(x[%d]) = %f\n",i,solucao[i],i, sol_anal[i]);  
  FILE *arq;  
  arq=fopen("saida.dat","w+b");  
  if (arq==NULL)  
    printf("Erro ao abrir arquivo\n");  
  else  
    {  
    printf("Arquivo aberto\n");  
    fwrite(solucao,sizeof(double),N,arq);  
    fwrite(sol_anal,sizeof(double),N,arq);  
    printf("Gravou\n");  
    fclose(arq);  
    }  
}

Observe um código em scilab para ler e fazer o gráfico das duas soluções:

N=101;  
x=linspace(0,1,N);  
arq=mopen(’/home/pasta/subpasta/subsubpasta/saida.dat’,’rb’)  
Snum=mget(N,’d’,arq)  
Sanal=mget(N,’d’,arq)  
mclose(arq)  
plot(x,Snum)  
plot(x,Sanal,’red’)

Creative Commons License Este texto é disponibilizado nos termos da licença Creative Commons Atribuição-CompartilhaIgual 3.0 Não Adaptada (CC-BY-SA 3.0). Página gerada em 19/8/2020 às 17:33:16.

Informe erros ou edite você mesmo!