Ir ao conteúdo
  • Cadastre-se

C Lista encadeada para ler arquivo em C


lets

Posts recomendados

Fiz esse código para ler os caracteres de um arquivo, guardar eles em uma lista, depois percorrer a lista informando se o código do caractere está entre o intervalo >=32 ou <=126 da tabela ASCII, mas ele não está me retornando nenhum resultado quando executo mesmo dentro do arquivo lido ter caracteres. Não consigo encontrar o erro

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

typedef struct no_lista No_Lista; 
typedef struct lista Lista;

struct no_lista{
    int numero;
    struct No_lista *proximo;
};

Lista* cria_lista(void){
	return NULL;
}

No_Lista* Insere_fim (No_Lista* l, int v){
	No_Lista* novo_no = (No_Lista*)malloc(sizeof(No_Lista));
	No_Lista* aux = l;
	novo_no->numero = v;
	if (aux == NULL){
		novo_no->proximo = l;
		//return novo_no;
	}
	else{
		while(aux->proximo != NULL){
			aux = aux->proximo;
		}
		novo_no->proximo = NULL;
		aux->proximo = novo_no;	
	return l;
	}
}

int main(){	
	int valor;
	No_Lista *l = (No_Lista*) malloc(sizeof(No_Lista));
	l = cria_lista();
	FILE *arquivo; 
	arquivo = fopen("arq.txt", "r");

 if (arquivo) 
       {
           do
            {
                fscanf(arquivo,"%d",&valor );                             
                l = Insere_fim(l,valor);   
                void percorre(No_Lista *l){
					No_Lista *no;
					no = l;
					while(no!=NULL){				
						if (valor >= 32 && valor <= 126){
						printf("\n O caractere: %c de codigo ASCII: %i contem na tabela de literais", valor, valor);
						no = no->proximo;
						}else{
							printf("\n O caractere: %c de codigo ASCII: %i nao contem na tabela de literais", valor, valor);
							fclose(arquivo);
						}					
						no = no->proximo;
					}	
				}
            } while(!feof(arquivo)); 
        }
return(0);
}



 

Link para o comentário
Compartilhar em outros sites

já tentou fazer algo menor?

 

Como uma lista encadeada simples

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

/* Tipos */
typedef struct NoLista
{
  int info;
  struct NoLista *proximo;
}lista_t;

void CriaNoLista(lista_t **l, int info);
void ApagaLista(lista_t *l);
void MostraLista(lista_t *l);

int main(void)
{
  char tecla;
  lista_t *inicio=NULL,*fim=NULL;
  do
  {
    int info;
    printf("\nDigite um numero:\t");
    scanf("%i%*c",&info);
    if(inicio==NULL)
    {
      CriaNoLista(&inicio,info);
      fim=inicio;
    }
    else
      CriaNoLista(&fim,info);
    printf("\nSair \nS/N:\t");
    scanf("%c%*c",&tecla);
  }while(tecla=='N'||tecla=='n');
  MostraLista(inicio);
  getchar();
  ApagaLista(inicio);
  return(0);
}

void CriaNoLista(lista_t **l, int info)
{
  lista_t *temp=malloc(sizeof(lista_t));
  if(temp==NULL)
    exit(EXIT_FAILURE);     /* ERRO */
  temp->proximo=NULL;
  temp->info=info;
  /* Primeiro nó na lista */
  if((*l)==NULL)
    (*l)=temp;
  /* Nó subsequente na lista */
  else
    (*l)=(*l)->proximo=temp;
}

void ApagaLista(lista_t *l)
{
  while(l)
  {
    lista_t *temp;
    temp=l->proximo;
    free(l);
    l=temp;
  }
}

void MostraLista(lista_t *l)
{
  while(l)
  {
    printf("\n%i",l->info);
    l=l->proximo;
  }
}

I'm sorry for crap code!

Link para o comentário
Compartilhar em outros sites

11 minutos atrás, Samns disse:

Comecei por uma assim, mas o problema é que preciso da parte que compara os caracteres do meu arquivo com os da tabela ASCII, isso está complicando o resto

ao meu ver o erro é na lista encadeada.qq_erros.thumb.png.c8dbb3e843f5c58fbefe20ed36d2cfd6.png

Quando tiver códigos que utilizam a memoria, eu recomendo que você utilize a diretiva acima(-fsanitize=address).

Link para o comentário
Compartilhar em outros sites

Seu programa está um pouco confuso ainda.

 

  • Talvez pudesse dar uma mensagem e simplesmente retornar se não consegue abrir o arquivo ao invés de colocar todo o código de main() dentro de um if()
  • Se o arquivo estiver vazio, do modo que escreveu vai tentar inserir algo que não leu... E no final do arquivo fscanf() não vai ler nada mas você vai tentar inserir mesmo assim
  • Você não testa ao inserir valores já existentes e não tenta classificar os valores ou algo assim. Se o critério é só o intervalo porque não insere logo no início?
  • Para que uma rotina que cria a lista se retorna NULL apenas?
  • Imagino que seja um enunciado. Poderia postar talvez. Porque inserir um valor inválido para depois descobrir? Porque não insere apenas os valores entre 32 e 126?

Sugiro

 

Escreva primeiro a leitura do arquivo, depois a criação da lista. Depois a crítica da lista.

Na criação da lista escreva primeiro a função que lista, depois a que insere.

Escreva SEMPRE main() como a primeira função, em especial se vai deixar seu programa para outros lerem. É assim que seu programa vai rodar, só que o sistema sempre sabe o endereço de main(). Você ou eu temos que procurar no texto...

 

Vou ler seu código melhor. Se mudou algo poste aqui,

Link para o comentário
Compartilhar em outros sites

Com ajuda eu cheguei a esse código, mas ainda estou com um problema

Quando leio um caractere especial como "ç" ele apresenta 3 resultados, dessa forma: https://imgur.com/a/Lqhi0qp 
O certo seria o programa parar a execução na primeira vez que aparecer um caractere que não existe nesse intervalo da tabela ASCII e exibir apenas uma vez a mensagem "o caractere de código 135 nao existe na tabela"
 

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

typedef struct no_lista No_Lista;
typedef struct lista Lista;

struct no_lista{
    int numero;
    struct no_lista *proximo;
};

No_Lista* cria_lista(void){
    return NULL;
}

No_Lista* Insere_fim (No_Lista* l, int v){

    No_Lista* novo_no = (No_Lista*)malloc(sizeof(No_Lista));
    No_Lista* aux = l;
    novo_no->numero = v;
    if (aux == NULL){
        novo_no->proximo = l;
        return novo_no;
    }
    else{
        while(aux->proximo != NULL){
            aux = aux->proximo;
        }
        novo_no->proximo = NULL;
        aux->proximo = novo_no;
    return l;
    }
}

void percorre(No_Lista *l){
   No_Lista *no;
   no = l;
   while(no!=NULL){
      int valor = (unsigned char) no->numero;
      if (valor >= 32 && valor <= 126){
         printf("\n O caractere: %c de codigo ASCII: %i contem na tabela de literais", valor, valor);
      }else{
         printf("\n O caractere codigo %i nao existe na tabela", valor);
      }
      no = no->proximo;
   }
}

int main(){
    unsigned char valor;
    No_Lista *l = (No_Lista*) malloc(sizeof(No_Lista));
    l = cria_lista();
    FILE *arquivo;
    arquivo = fopen("arq.txt", "r");
   if (arquivo){
      puts("I get it!");
      do
      {
         fscanf(arquivo,"%c",&valor);
         l = Insere_fim(l, (int)valor);
      } while(!feof(arquivo));
      fclose(arquivo);
   }
   percorre(l);
   return 0;
}

 

Link para o comentário
Compartilhar em outros sites

Parece que você sequer corrigiu o problema com EOF de que falei.

Ler esses caracteres usando scanf() é um pesadelo. Tem muitas discussões sobre isso aqui. Tem a ver com páginas de código e o modo como o sistema que está usando trata esses caracteres. Teste tudo antes de se preocupar com isso. Use apenas um arquivo com umas poucas letras e confirme que o resto funciona (a lista e a leitura do arquivo)

adicionado 17 minutos depois
    No_Lista *l = (No_Lista*) malloc(sizeof(No_Lista));
    l = cria_lista();

Estava olhando o que mais mudou em seu código...

 

Como te disse, cria_lista() não tem razão de ser, porque não recebe parametro algum e apenas retorna NULL. Mas usar isso depois de malloc é pior ainda. Só vai perder o valor alocado em l...

 

Insere_fim() funciona com uma lista vazia?

percorre() funciona com uma lista vazia?

 

Sugestão:

 

Escreva uma outra, mostra_lista() por exemplo, que apenas faz o óbvio. E TESTE antes algo assim

    No_lista* l = cria_lista();
    mostra_lista(l);
    insere_fim(l,1);
    mostra_lista(l);
    insere_fim(l,2);
    mostra_lista(l);
    insere_fim(l,3);
    mostra_lista(l);

// isso deve rodar antes de tudo...
// nao misture as coisas.

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...