Ir ao conteúdo
  • Cadastre-se

C Retornar Ponteiro de struct


Ir à solução Resolvido por Flávio Pedroza,

Posts recomendados

A função abaixo faz uma consulta do CPF no "banco de dados" e retorna um ponteiro para o struct cliente encontrado, ou NULL caso não houver um CPF correspondente:

struct Cliente *buscaCadastro(){
    FILE *arquivo;

    char cpf[16];
    struct Cliente clienteAlvo;
    struct Cliente *aux = &clienteAlvo;

    arquivo = fopen("Clientes.dat", "rb");
        
        if(arquivo == NULL){
            fprintf(stderr, "Erro ao ler o arquivo\n");
            exit(1);
        }

        printf("CPF: ");
        setbuf(stdin, NULL);
        scanf("%[^\n]s", cpf);

        fread(&clienteAlvo, sizeof(struct Cliente), 1, arquivo);
        do{
            if(!strcmp(clienteAlvo.cpf,cpf)){
                printf("O CPF pertence ao cliente \"%s\" já cadastrado\n", clienteAlvo.nome); //imprime:O CPF pertence ao cliente "Paulo Cesar" já cadastrado
                printf("O CPF pertence ao cliente \"%s\" já cadastrado\n", aux->nome); //imprime:O CPF pertence ao cliente "Paulo Cesar" já cadastrado
                return aux;
            }
         fread(&clienteAlvo, sizeof(struct Cliente), 1, arquivo);
        }while(!feof(arquivo));
    fclose(arquivo);

    printf("O CPF não está cadastrado\n");
    return NULL;
}

 

A função acima retorna para a função abaixo, que recebe o struct em um ponteiro, porém somente o campo "nome" não é impresso (a representação da impressão esta comentada ao lado de cada linha printf):

 

O campo parece ser pedido durante a passagem, gostaria de saber o que esta havendo !!

 

void hotel (){

    struct Cliente *cliente = NULL;
    int opcao;
    do{
        menu();
        opcao = leOpcao();

        switch (opcao){
        case 1:
            cliente = buscaCadastro();
            if(cliente != NULL)
                printf("O CPF pertence ao cliente \"%s\" %d já cadastrado\n", cliente->nome);//imprime:O CPF pertence ao cliente "" já cadastrado
            else
                printf("O CPF não está cadastrado\n");
            break;
        case 2:
            //cadastraNovo();
            break;
        case 3:
            //atualizaCadastro();
            break;
        case 4:
            //removeCadastro();
            break;
        case 5:
            //imprimeCadastro();
            break;
        case 6:
            //geraRelatorio();
            break;
        case 9:
            break;
        default:
            printf("Opcao invalida\n");
            break;
        }
    }while(opcao != 9);
}

 

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

 

struct Cliente *buscaCadastro(){
    FILE *arquivo;

    char cpf[16];
    struct Cliente clienteAlvo;
    struct Cliente *aux = &clienteAlvo;

 

  • já que vai buscar o cliente no arquivo talvez devesse passar o nome do arquivo como parâmetro
  • defina um tipo Cliente como sendo a estrutura para não ter que ficar repetindo struct a toda hora
  • você NÃO pode retornar um endereço local de sua função para o chamador. clienteAlvo só existe dentro da função. Ou você aloca uma estrutura na função e devolve o endereço ou você aloca clienteAlvo em main() e passa o endereço para a função, o que parece ser mais simples já que trata um cliente por vez
  • se não é o enunciado que pede e se não tem milhares de clientes no arquivo o mais comum é ler todo o arquivo e montar um vetor de estruturas na memória
  • se você gravou o arquivo na mesma máquina deve funcionar, mas o certo é se certificar de que a estrutura que gravou está sendo lida todinha de volta, testando no programa que grava e não no que lê. Pode ser que o compilador inclua bytes de alinhamento em sua estrutura quando grava e tem que ler de mesmo modo. Para testar apenas mostre um a um na tela agora para vez se não está desalinhando, depois de corrigir o erro do ponteiro...


 

 

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

@arfneto mas se peço pra imprimir idade do cliente, por exemplo, na função hotel ela imprime normal. Parece que apenas string do ponteiro não está sendo passado.

 

Eu acredito que como eu estou retornando um ponteiro (endereço da variável) não iria ter problema já que a variável só exite dentro da função onde foi criada mas o endereço é igual para qualquer função que o receber, me corrija se eu estiver errado.

Link para o comentário
Compartilhar em outros sites

4 minutos atrás, Gabriel Barbosa Brandao disse:

Eu acredito que como eu estou retornando um ponteiro (endereço da variável) não iria ter problema já que a variável só exite dentro da função onde foi criada mas o endereço é igual para qualquer função que o receber, me corrija se eu estiver errado

 

Está errado. Eu te disse duas maneiras de escrever isso.

Sobre a teoria procure em seu livro  por escopo --- scope .

adicionado 2 minutos depois
6 minutos atrás, Gabriel Barbosa Brandao disse:

acredito que como eu estou retornando um ponteiro (endereço da variável) não iria ter problema já que a variável só exite dentro da função onde foi criada mas o endereço é igual para qualquer função que o receber

 

:) ainda sobre isso: o endereço é igual, só que não tem mais nada lá. Ou pode ter. Fora da função vai depender do sistema o que fazer com o conteúdo daquele endereço. 

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

  • Solução

Uma possível solução para o seu problema:

typedef struct {
...
} Cliente

Cliente *buscaCadastro(){
    FILE *arquivo;

    char cpf[16];
	//agora a variável está permanentemente alocada na memória, até você chamar free
    Cliente* clienteAlvo = (Cliente *)malloc(sizeof(Cliente));
    //struct Cliente *aux = &clienteAlvo;

 

Não esqueça de liberar a memória alocada com free.

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