Ir ao conteúdo
  • Cadastre-se
João Victor Simonassi Farias

Problemas com a utilização de ponteiros

Recommended Posts

Boa tarde! Estou desenvolvendo um programa na faculdade que cadastra produtos e depois realiza uma venda. Esta venda é salva em .txt e será usada posteriormente em outro programa. Entretanto, estou com algumas dificuldades. Segue parte do código onde se encontram os problemas:

 

void venda_dados(Dados *dados, FILE *arquivo) {

	int achou = 0, volta, qnt, conta = 0, chave; // Conta vai marcar o número de pedidos na fila
    float valor =0, preco;

        do{
        		if (!checa_vazio(principal)) {
                		printf("Digite o código do produto: \n--> ");
                		scanf("%d", &chave);


        printf("\nCadastro:\n");
        for ( ; dados != NULL; dados = dados->proximo)
		 {
                 if (dados->cod == chave)
				 {

                        printf("------------------------\n");
                        printf("Nome do produto: %s\n", dados->nome);
                        printf("Código do produto: %d\n", dados->cod);
                        printf("R$ %4.2f reais \n", dados->preco);
                        printf("------------------------\n");
                        achou++;
                }
        }

        if (achou == 0)
                printf("Nenhum resultado encontrado.\nPressione uma tecla para continuar.\n");
        else{
                printf("Foram encontrados %d registros. \n\n", achou);
															   conta++;  //adiciona 1 pedido no .txt

        printf(" Quantidade: ");
		scanf("%d", &qnt);

						 arquivo = fopen("pedido.txt", "a"); //criando arquivo .txt

                        				 if(arquivo == NULL)
                                	     printf("Erro ao se comunicar com o servidor da cozinha!"); // não conseguiu salvar o .TXT

                         				 else {
    			 						        fprintf(arquivo,"Pedidos na fila: %d\n\n", conta);
    			 						        fprintf(arquivo,"-------------------------\n");
   			    						        fprintf(arquivo," NOME: %s \n", dados->nome);  // Vai escrever isso no .txt  OU PELO MENOS DEVERIA
   			    						        fprintf(arquivo," QUANTIDADE: %d\n", qnt);
   			    						        fprintf(arquivo,"-------------------------");
   		              	                      }

       

		valor = valor + ((dados->preco) * qnt); // CÁLCULO NÃO FUNCIONA
        printf("Valor total = %4.2f", valor);
        }
        
        
        printf("\nDigite 1 para adicionar outro produto a venda, ou 0 para sair ");
        scanf("%d", &volta);
        }// chave do if lá em cima
        }while(volta == 1);
}

O programa compila e executa corretamente (Lembrando que essa é só a função que está com problema), mas quando executo, acontece o seguinte:

 

1° problema: Na linha  "fprintf(arquivo," NOME: %s \n", dados->nome);" o programa para de funcionar. Se eu tirar o apontamento "dados->nome", funciona tranquilo. O ponteiro " *arquivo " usado como argumento na função foi declarado globalmente lá em cima.;

 

2° problema: Na linha da variável acumulativa "valor = valor + ((dados->preco) * qnt);" Acontece o mesmo problema do apontamento (retirei a parte do arquivo em cima pra poder chegar a essa parte do código sem erros);

 

3° problema: Esse me parece ser um pouco mais simples, mas ainda não consegui resolver. Se eu ignorar os erros listados acima com um comentário ou algo do tipo, o produto é cadastrado, mas quando "volta = 1", indicando que eu quero adicionar mais um produto a venda, ou seja, retornando ao início do "do while" o programa me pede o código, mas não entre no "for". Não lista o nome do produto e cai direto na quantidade.

 

É a primeira vez que estou trabalhando ponteiros nessa proporção e estou bem perdido. Qualquer coisa eu posso postar o código completo. Desde já, agradeço a ajuda.

Compartilhar este post


Link para o post
Compartilhar em outros sites
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct dados_t
{
	char nome[32];
}Dados;

int main()
{
	FILE *arquivo;
	arquivo = fopen("test.txt", "w");

	Dados* dados;
	dados = (Dados*)malloc(sizeof(Dados));

	strcpy(dados->nome, "Hello");

	fprintf(arquivo, " NOME: %s \n", dados->nome);  // Vai escrever isso no .txt  OU PELO MENOS DEVERIA

	free(dados);
	fclose(arquivo);
	return 0;
}

Poderia postar como está a sua struct Dados?

Compartilhar este post


Link para o post
Compartilhar em outros sites

É difícil dizer onde tem erro sem ver o código inteiro...

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
6 horas atrás, MassakiMsk disse:

É difícil dizer onde tem erro sem ver o código inteiro...

Exato! Por isso nem respondi. Mania tem os usuários de soltar códigos a conta-gotas.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <conio.h>
#include <locale.h>
#include <windows.h>

#define BUFFER 64


FILE *arquivo; // ponteiro para armazenar as compras.

/* Estrutura da lista declarada para armazenar dados. */
typedef struct lista {
        char *nome;
        float preco;
        int cod;
        float valor;
    //  char *obs;  verificar VARIÁVEL PARA ARMAZENAR TEXTO || QUERIA COLOCAR MAIS UM CAMPO NO CADASTRO, MAS AINDA TIVE ALGUNS PROBLEMAS E DEIXEI ASSIM mesmo POR ENQUANTO
        struct lista *proximo;
} Dados;

/* Prototipo das funcoes de manuseio dos dados. */
Dados *inicia_dados(char *nome, float preco, int cod/*,char *obs*/);
Dados *insere_dados(Dados *dados, char *nome, float preco, int cod/*, char *obs*/);
void exibe_dados(Dados *dados);
void busca_dados(Dados *dados, int chave);
Dados *deleta_dados(Dados *dados);
int checa_vazio(Dados *dados);

/* Prototipo das funcoes do menu.*/
void insere(void);
void exibe(void);
void busca(void);
void deleta(void);

/* Inicializa a estrutura de dados principal. */
Dados *principal = NULL;

//**************************************************************  FUNÇÃO INICIA_DADOS (STRUCT) *************************************************************************
/* Cria a nova lista apontando o proximo no para NULL. */
Dados *inicia_dados(char *nome, float preco, int cod/*, char *obs*/) {

        Dados *novo;

        novo = (Dados *)malloc(sizeof(Dados));

        novo->nome = (char *)malloc(strlen(nome)+1);
        strncpy(novo->nome, nome, strlen(nome)+1);

        novo->preco = preco;
        novo->cod = cod;
    //	novo->obs = obs;

       /*	novo->nome = (char*)malloc(strlen(obs)+1);
        strncpy(novo->obs, obs, strlen(obs)+1);*/

        novo->proximo = NULL;

        return novo;
}


//**************************************************************  FUNÇÃO INSERE_DADOS (STRUCT) *************************************************************************
/* Como a lista nao esta mais vazia, apontamos o proximo no para lista anterior. */
Dados *insere_dados(Dados *dados, char *nome, float preco, int cod/*, char *obs*/) {

        Dados *novo;

        novo = (Dados *)malloc(sizeof(Dados));

        novo->nome = (char *)malloc(strlen(nome)+1);
        strncpy(novo->nome, nome, strlen(nome)+1);

        novo->preco = preco;
        novo->cod = cod;

      /*  novo->nome = (char*)malloc(strlen(obs)+1);
        strncpy(novo->obs, obs, strlen(obs)+1);*/

        novo->proximo = dados;

        return novo;
}


//**************************************************************  FUNÇÃO EXIBE_DADOS *************************************************************************
/* Percorre todos os campos da lista e imprime ate o ponteiro proximo chegar em NULL. */
void exibe_dados(Dados *dados) {

        fprintf(stdout, "Cadastro:\n\n");

        fprintf(stdout, "------------------------\n");

        for (; dados != NULL; dados = dados->proximo) {
                fprintf(stdout, "Nome do produto: %s\n", dados->nome);
                fprintf(stdout, "Código do produto: %d\n", dados->cod);
                fprintf(stdout, " R$: %4.2f reais \n", dados->preco);
               // fprintf(stdout, " Anotações: %s \n", dados->obs);
                fprintf(stdout, "------------------------\n ");
        }
        printf("Pressione uma tecla para continuar.");
        getch();
}

//**************************************************************  FUNÇÃO BUSCA_DADOS *************************************************************************
/* Percorre cada ponta comparando o nome com a chave. */
void busca_dados(Dados *dados, int chave) {

        int achou = 0;

        fprintf(stdout, "Cadastro:\n\n");
        for (; dados != NULL; dados = dados->proximo) {
                if (dados->cod == chave) {

                        fprintf(stdout, "------------------------\n");
                        fprintf(stdout, "Nome do produto: %s\n", dados->nome);
                        fprintf(stdout, "Código do produto: %d\n", dados->cod);
                        fprintf(stdout, "R$ %4.2f reais \n", dados->preco);
                     //   fprintf(stdout, " Anotações: %s \n", dados->obs);
                        fprintf(stdout, "------------------------\n");
                        achou++;
                }
        }

        if (achou == 0)
                fprintf(stdout, "Nenhum resultado encontrado.\nPressione uma tecla para continuar.\n");
        else
                fprintf(stdout, "Foram encontrados %d registros. \nPressione uma tecla para continuar.\n", achou);

        getch();
}

//**************************************************************  FUNÇÃO DELETA_DADOS *************************************************************************
/* Deleta o ultimo registro inserido. */
Dados *deleta_dados(Dados *dados) {

        Dados *novo;

        novo = dados->proximo;

        free(dados->nome);
        free(dados);
     //   free(dados->obs); VOU DEIXAR DE COMENTÁRIO porque É UM PONTEIRO

        fprintf(stdout, "O ultimo registro inserido foi deletado com sucesso.\\n");
        Sleep(1);

        return novo;
}

//**************************************************************  FUNÇÃO CHECA_VAZIO *************************************************************************
/* apenas checa se a lista é NULL ou nao. */
int checa_vazio(Dados *dados) {

        if (dados == NULL) {
                fprintf(stdout, "Lista vazia!\n");
                Sleep(1);
                return 1;
        } else
                return 0;
}


//**************************************************************  FUNÇÃO VENDA_DADOS *************************************************************************
void venda_dados(Dados *dados, FILE *arquivo) {

	int achou = 0, volta, qnt, conta = 0, chave; // Conta vai marcar o número de pedidos na fila
    float valor =0, preco;

        do{
        		if (!checa_vazio(principal)) {
                		fprintf(stdout, "Digite o código do produto: \n--> ");
                		scanf("%d", &chave);


        printf("\nCadastro:\n");
        for ( ; dados != NULL; dados = dados->proximo)
		 {
                 if (dados->cod == chave)
				 {

                        printf("------------------------\n");
                        printf("Nome do produto: %s\n", dados->nome);
                        printf("Código do produto: %d\n", dados->cod);
                        printf("R$ %4.2f reais \n", dados->preco);
                   //     fprintf(stdout, " Anotações: %s \n", dados->obs);
                        printf("------------------------\n");
                        achou++;
                }
        }

        if (achou == 0)
                printf("Nenhum resultado encontrado.\nPressione uma tecla para continuar.\n");
        else{
                printf("Foram encontrados %d registros. \n\n", achou);
															   conta++;  //adiciona 1 pedido no .txt

        printf(" Quantidade: ");
		scanf("%d", &qnt);


						 arquivo = fopen("pedido.txt", "w"); //criando arquivo .txt

                        				 if(arquivo == NULL)
                                	     printf("Erro ao se comunicar com o servidor da cozinha!"); // não conseguiu salvar o .TXT

                         				 else {
    			 						        fprintf(arquivo,"Pedidos na fila: %d\n\n", conta);
    			 						        fprintf(arquivo,"-------------------------\n");
   			    						        fprintf(arquivo," NOME: %s \n", dados->nome);  // Vai escrever isso no .txt
   			    						        fprintf(arquivo," QUANTIDADE: %d\n", qnt);
   			    						        fprintf(arquivo,"-------------------------");
   		              	                      }

       
		valor = valor + ((dados->preco) * qnt);
        printf("Valor total = %4.2f", valor);
        }
        
        
        printf("\nDigite 1 para adicionar outro produto a venda, ou 0 para sair ");
        scanf("%d", &volta);
        }// chave do if lá em cima
        }while(volta == 1);
}



//**************************************************************  FUNÇÃO INSERE  *************************************************************************

/* Obtem os dados necessarios para chamar as funcoes de manuseio de dados. */
void insere(void) {

        char *nome;
        int cod;
        float preco;
    //    char *obs;

        nome = (char *)malloc(BUFFER);
       // obs = (char*)malloc(BUFFER);

        printf("\n Digite o nome do produto: ");
        scanf("%s", nome); // TESTAR

        printf("\n Digite o código do produto: ");
        scanf("%d", &cod);

        printf("\n Digite o preço: ");
        scanf("%f", &preco);


        /*printf(stdout, "Anotações sobre o produto(Ex: Ingredientes, modo de preparo...): ");

        scanf("%d", &obs);
        fprintf(stdout, "\n");*/

        printf("\n\n PRODUTO CADASTRADO!");

        if (principal == NULL)
                principal = inicia_dados(nome, preco, cod/*, obs*/);
        else
                principal = insere_dados(principal, nome, preco, cod/*, obs*/);
}

//**************************************************************  FUNÇÃO EXIBE  *************************************************************************
void exibe(void) {

        if (!checa_vazio(principal))
                exibe_dados(principal);

}

//**************************************************************  FUNÇÃO BUSCA  *************************************************************************
void busca(void) {

        int chave;

        if (!checa_vazio(principal)) {

                printf("Digite o código do produto: \n--> ");
                scanf("%d", &chave);

                busca_dados(principal, chave);
                getch();
        }
}
//**************************************************************  FUNÇÃO DELETA  *************************************************************************
void deleta(void) {

        if (!checa_vazio(principal))
                principal = deleta_dados(principal);
}

//**************************************************************  FUNÇÃO VENDA  *************************************************************************

void venda(void){
                venda_dados(principal, arquivo);
            }



//**************************************************************  FUNÇÃO MAIN  *************************************************************************

int main() {

        int escolha;

        do {
		setlocale(LC_ALL, "Portuguese");
        	    system("color 4E");
                system("cls");
                printf("\n\t   LANCHONETE \n\n");
                printf("   Nova venda ---------- [1] \n");
                printf("   Cadastrar produto --- [2] \n");
                printf("   Exibir produtos ----- [3] \n");
                printf("   Buscar produto ------ [4] \n");
                printf("   Deletar Dados ------- [5] \n");
                printf("   Sair ---------------- [6] \n");

                printf("\n   Escolha uma opção: ");
                scanf("%d", &escolha);
                system("cls");
                if(escolha == 1){
			      				printf("\t NOVA VENDA\n\n");
                			    venda();
							    }

                else if(escolha == 2){
                				printf("\t CADASTRO DE PRODUTOS\n\n");
                                insere();
                                Sleep(1);
					                 }

                else if(escolha == 3){
                				     printf("\t EXIBIR PRODUTOS\n\n");
                                     exibe();
								     }

                else if(escolha == 4){
                					 printf("\t BUSCA DE PRODUTOS\n\n");
                                     busca();
                                     }

            	else if(escolha == 5){
							    	printf("\t DELETAR DADOS\n\n");
                                    deleta();

                                     }
                else if(escolha == 6)
                                exit(0);

                else{
                                printf("Digite uma opcao valida!\n");
                                Sleep(1);
                }


        }

        while (escolha > 0); /* Loop Principal. */

        return 0;
}

 

adicionado 58 minutos depois

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Agora sim. A questão é que você está perdendo a referência do ponteiro do tipo Dados na função de adicionar venda.

Percebe que nesse for você vai percorrer todas as posições até que seja null?

Citação

for ( ; dados != NULL; dados = dados->proximo)

Então, na hora de você salvar o nome no txt ele está tentando acessar o nome de um ponteiro nulo, você pode resolver isso adicionando um break dentro do if, ou seja, quando encontrar o código ele sai do ciclo for com o ponteiro na posição correta.

Outro problema é quando o usuário deseja inserir uma nova venda, como você está movimentando o ponteiro recebido como parâmetro não vai ter como começar o ciclo for des do começo, para resolver isso basta criar um novo ponteiro Dados que só sirva para resetar o ponteiro que está sendo usado nessa função.

Outro ponto é que se você volta pro menu e seleciona cadastrar nova venda todas as outras informações do txt vão ser perdidas porque você está criando o arquivo com "w", crie com "a" para não acontecer isso.

 

Outra coisa que eu esqueci de dizer, você não está fechando o txt:

Citação

fclose(arquivo);

Sem isso nada vai ser salvo no arquivo, coloque depois de salvar os dados.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Faça um ponteiro de "backup" que só sirva para guardar a primeira posição. Quando for fazer outra venda é só igialar o ponteiro que está sendo usado com esse backup.

Tipo, quando entrar na função, na hora de criar as variáveis você faz Dados b_dados = dados;

E toda vez que for inserir nova venda é só fazer dados = b_dados; 

Assim vai poder comparar todos os produtos de novo.

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro 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 publicações 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

×