首页 > 解决方案 > 文件在第二次打开时指向缓冲区的结尾(我猜)

问题描述

我快疯了。所以我决定寻求帮助。我编写了以下例程,它创建了所有可能的具有 n 个顶点的彩色图(有一些限制)。首先,它创建具有 n - 1 个顶点的所有可能的彩色图形并保存在 txt 文件中,并使用较小的图形来创建较大的图形。

问题是当我需要第二次打开文件时。程序的行为就像我们在缓冲区的末尾一样。有人可以帮助我吗?

我创建了一个简单的例子。请注意,理论上,该程序将打印两次相同的信息。但这并不快乐。

#include<stdlib.h>
#include<stdio.h>
#include<algorithm>

int main(){
  int n;
  int r;
  lgrafo *tg;
  n = 4;
  r = 5;

 tg =  criarListaTT(n, r);
 imprimeLista(tg);
 
 tg =  criarListaTT(n, r);
 imprimeLista(tg);
  
  
}

lgrafo *criarListaTT(int n, int r){
  lgrafo *lg, *aux, *atual, *auxH, *aux2;
  int c = n*(n-1)/2;
  long t;
  int q;
  grafo *g;
  int *v, *lim;
  
  if(n >= 3){
    printf("Lendo lista %d...\n", n-1);
    aux = abrirLista(n-1, r);
    if(aux == NULL){
      printf("Lista não encontrada!\nCriando Lista!\n");
      aux = criarListaTT(n-1, r);
    }
  }
  else{
    if(n < 2)
      return NULL;
    else{
      lg = criarLista(NULL, NULL, NULL);
      atual = lg;
      g = (grafo *)malloc(sizeof(grafo));
      g->n = n;
      g->edge = (int *)malloc(sizeof(int)*c);
      for(int i = 0; i <= r; i++){
    g->edge[0] = i;
    atual->next = criarLista(g, atual, NULL);
    atual = atual->next;
      }
      liberarGrafo(g);
      salvarLista(lg, n, r);
      return lg;
    }
  }

  printf("Lista %d criada/lida!\nCriando Lista%d\n", n-1, n);
  lg = criarLista(NULL, NULL, NULL);
  atual = lg;

  //tem que considerar TODAS AS ARESTAS ATÉ R

  g = (grafo *)malloc(sizeof(grafo));
  g->edge = (int *)malloc(sizeof(int)*c);
  g->n = n;
  
  auxH = aux;
  aux = aux->next;
  v = (int *)malloc(sizeof(int)*(n-1));
  lim = (int *)malloc(sizeof(int)*(n-1));
  for(int i = 0; i < n - 1; i++){
    lim[i] = r;
  }
  while(aux != NULL){
    for(int i = 0; i < n - 1; i++){
      for(int j = i+1; j < n - 1; j++){
    g->edge[formu(i, j, n)] = aux->g->edge[formu(i, j, n-1)];
      }
      g->edge[formu(i, n-1, n)] = 0;
      v[i] = 0;
    }

    do{
      for(int i = 0; i < n-1; i++){
    g->edge[formu(i, n-1, n)] = v[i];
      }
      q = 1;

      for(int i = 0; i < n-1 && q == 1; i++){
    if(g->edge[formu(i, n-1, n)] != 0){
      for(int j = i+1; j < n-1 && q == 1; j++){
        if(g->edge[formu(j, n-1, n)] != 0 && g->edge[formu(i, j, n)] != 0){
          if(g->edge[formu(i,n-1,n)] + g->edge[formu(j,n-1,n)] + g->edge[formu(i,j,n)] > r)
        q = 0;
        }
      }
    }
      }

      if(q == 1){
    aux2 = lg->next;
    t = 0;
    while(aux2 != NULL && t == 0){
      t = isomorfo(aux2->g, g, r);
      if(t == 1)
        q = 0;
      aux2 = aux2->next;
    }
      }
      
      if(q == 1){
    atual->next = criarLista(g, atual, NULL);
    atual = atual->next;
      }
    }while(ncontEE(v, lim, n-1, r));

    aux = aux->next;
  }

  salvarLista(lg, n, r);
  liberarLista(auxH);
    

  return lg;  
}

void imprimeGrafo(grafo *g){
  for(int i = 0; i < g->n*(g->n - 1)/2; i++)
    printf("%d ", g->edge[i]);
  printf("\n");
}

void imprimeLista(lgrafo *lg){
  lgrafo *atual;
  atual = lg->next;
  while(atual != NULL){
    imprimeGrafo(atual->g);
    atual = atual->next;
  }
}

int ncontEE(int *v, int *lim, int n, int r){
  int vai = 1;
  int t = n - 1;
  while(vai == 1 && t >= 0){
    v[t]++;
    if(v[t] > lim[t]){
      v[t] = 0;
      t--;
    }
    else
      vai = 0;
  }

  if(t < 0)
    return 0;
  return 1;
}

int formu(int i, int j, int n){ //usado para acessar as possicoes da matriz de ajacencia. Os vertices sao enumerados de 0 até n-1 
  int t;
  if(i < j){
    t = (2*n - i - 1)*i/2;
    return t + (j - i) - 1;
  }
  else{
    t = (2*n - j - 1)*j/2;
    return t + (i - j) - 1;
  }
}

grafo *cloneGrafo(grafo *g){
  if(g == NULL)
    return NULL;

  grafo *h;
  h = (grafo *)malloc(sizeof(grafo));
  h->n = g->n;
  h->edge = (int *)malloc(sizeof(int)*g->n*(g->n-1)/2);
  for(int i = 0; i < h->n*(h->n-1)/2; i++){
    h->edge[i] = g->edge[i];
  }

  return h;
}

void liberarGrafo(grafo *g){
  if(g != NULL){
    if(g->edge != NULL)
      free(g->edge);
    free(g);
  }
}

void removeDaLista(lgrafo *lg){
  if(lg != NULL){
    if(lg->prev != NULL){
      lg->prev->next = lg->next;
    }
    if(lg->next != NULL){
      lg->next->prev = lg->prev;
    }
    liberarGrafo(lg->g);
    free(lg);
  }
}

void liberarLista(lgrafo *lg){
  lgrafo *aux;
  aux = lg->next;
  while(aux != NULL){
    removeDaLista(aux);
    aux = lg->next;
  }
  aux = lg->prev;
  while(aux != NULL){
    removeDaLista(aux);
    aux = lg->prev;
  }
  removeDaLista(lg);
}

lgrafo *criarLista(grafo *g, lgrafo *prev, lgrafo *next){
  lgrafo *lg;
  lg = (lgrafo *)malloc(sizeof(lgrafo));
  lg->next = next;
  lg->prev = prev;
  lg->g = cloneGrafo(g);
  return lg;
}
  
lgrafo *abrirLista(int n, int r){
  char name[100];
  FILE *f;
  lgrafo *lg, *atual;
  grafo *g;
  int c = n*(n-1)/2;
  
  snprintf(name, sizeof(name), "n%dr%d.txt", n, r);
  f = fopen(name, "r");
  if(f == NULL)
    return NULL;

  rewind(f);
  g = (grafo *)malloc(sizeof(grafo));
  g->n = n;
  g->edge = (int *)malloc(sizeof(int)*c);

  lg = criarLista(NULL, NULL, NULL);
  atual = lg;
  
  while(feof(f)){
    for(int i = 0; i < c; i++){
      fscanf(f, "%d", &g->edge[i]);
    }
    atual->next = criarLista(g, atual, NULL);
    atual = atual->next;
  }

  liberarGrafo(g);
  rewind(f);
  fclose(f);

  return lg;  
}

void salvarLista(lgrafo *lg, int n, int r){
  FILE *f;
  char name[100];
  lgrafo *atual;
  int c = n*(n-1)/2;
  
  if(lg == NULL)
    if(lg->next == NULL)
      exit(0);

  snprintf(name, sizeof(name), "n%dr%d.txt", n, r);
  f = fopen(name, "w");
  if(f == NULL)
    exit(0);

  atual = lg->next;
  while(atual != NULL){
    for(int i = 0; i < c; i++){
      fprintf(f, "%d ", atual->g->edge[i]);
    }
    fprintf(f, "\n");
    atual = atual->next;
  }
  rewind(f);
  fclose(f);
}

谢谢

标签: c++cfile

解决方案


推荐阅读