Ir ao conteúdo
  • Cadastre-se

Problemas com a utilização de ponteiros


Posts recomendados

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.

Link para o comentário
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?

Link para o comentário
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

 

Link para o comentário
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.

Link para o comentário
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.

 

 

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

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