Ir ao conteúdo
  • Cadastre-se
Jessé P. de Melo

C como trabalhar com ponteiro nulo sem ele apontar para qlq lugar

Recommended Posts

Boa tarde.

Estou fazendo o exercício : Faca um programa que leia um vetor com dados de 5 livros: tıtulo (maximo 30 letras),  autor (maximo 15 letras) e ano. Procure um livro por tıtulo, perguntando ao usuario qual  tıtulo deseja buscar. Mostre os dados de todos os livros encontrados.

Desenvolvi a solução parcial que segue abaixo, no entanto não tenho experiencia com ponteiros. Sei que ao se atribuir zero ha um ponteiro (linha 45)  ele aponta para qualquer lugar, mas como resolvo esse problema de outra maneira? Tentei criar um vetor te tamanho igual ao titulo e apontar para ele, não resolveu...Da maneira que esta imprimi a linha que encontra e as outras aponta para lugares aleatórios.

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

void main(void){
    char pesquisar[31];

    struct colecao{
        char titulo[31];
        char autor[16];
        int ano;
    };

    struct colecao livros[5];
    struct colecao encontrados[5];

    for(int x=0;x<5;x++){
        encontrados[x].titulo[0]=' ';
    }

    for(int x=0;x<5;x++){
        printf("Digite o titulo ");
        scanf("%s",&livros[x].titulo);
        fflush(stdin);
        printf("Autor: ");
        scanf("%s",&livros[x].autor);
        fflush(stdin);
        printf("Ano: ");
        scanf("%i",&livros[x].ano);
        fflush(stdin);
        printf("\n");
    }

    for(;;){
        printf("Digite um titulo para pesquisar: ");
        scanf("%s",&pesquisar);
        fflush(stdin);
        printf("\n");


        int z=0;

        for(int x=0;x<5;x++){

            char *ret=0;
            ret=strstr(livros[x].titulo,pesquisar);
            if(ret!=0){
                encontrados[z]=livros[x];
                z++;
            }
        }
        for(int x=0;x<5;x++){
            if(encontrados[x].titulo[0]!=0){
                printf("\nTitulo: %s\tAutor: %s\tAno: %i\n\n",encontrados[x].titulo,encontrados[x].autor,encontrados[x].ano);
            }
        }
    }
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Do Ponteiro

Ponteiro nulo é um ponteiro que não aponta, ou seja, ponteiro de valor 0, porque um ponteiro somente aponta quando seu valor é diferente de 0. Esse é conceito fechado em ciência da computação, pois não existe outro valor diferente de zero para ponteiro nulo.

https://www.geeksforgeeks.org/few-bytes-on-null-pointer-in-c/

 

 

Da Função strstr( char * str1, char * str2 )

A função retorna ponteiro nulo se; o conjunto str2 não está contido em str1, acredito que isso você já sabe! Se str2 e subconjunto de str1, ou seja, str2 está contido em str1 então a função retorna um valor inteiro sem sinal diferente de 0 (ou ponteiro) que é o local na memória da primeira ocorrência de str2 em str1.

http://www.cplusplus.com/reference/cstring/strstr/

 

 

10 horas atrás, Jessé P. de Melo disse:

Sei que ao se atribuir zero ha um ponteiro (linha 45)  ele aponta para qualquer lugar,

  • Está sabendo errado, ao atribuir 0 a um ponteiro ele aponta para lugar nenhum, ou melhor, ele não aponta.

 

Até aqui consegui entender que ...

        for(int x=0;x<5;x++){

            char *ret=0;
            ret=strstr(livros[x].titulo,pesquisar);
            if(ret!=0){
                encontrados[z]=livros[x];
                z++;
            }

Variável do tipo char point: ret; inicializada com null point e está corretamente inicializada. Se quiser existe outras forma de fazer isso:

        for(int x=0;x<5;x++){

            char * ret = NULL;
            ret=strstr(livros[x].titulo,pesquisar);
            if(ret!=0){
                encontrados[z]=livros[x];
                z++;
            }

o resultado é o mesmo que antes. Caso queira expandir o conceito ainda poderia fazer assim:

        for(int x=0;x<5;x++){

            void * ret = ((void *)NULL);
            ret=strstr(livros[x].titulo,pesquisar);
            if(ret != ((void *)NULL)){
                encontrados[z]=livros[x];
                z++;
            }

ret é um ponteiro genérico que foi inicializado apontando para lugar nenhum, ou é ponteiro que não aponta.

 

 

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

hum...Realmente continuou dando o mesmo problema.

Então o erro ta aqui...

4 horas atrás, Jessé P. de Melo disse:

for(int x=0;x<5;x++){ if(encontrados[x].titulo[0]!=0){ printf("\nTitulo: %s\tAutor: %s\tAno: %i\n\n",encontrados[x].titulo,encontrados[x].autor,encontrados[x].ano); }

Em vez de comparar com 0 vou comparar com as letras do alfabeto.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ja tentei tentei e tentei não estou conseguindo. Tem como alguém corrigir para eu ver exatamente onde errei?Está imprimindo um monte de caracteres nada a ver no títulos autor e ano nos índices encontrados que não são compatíveis com a string procurada; O código tem algumas redundâncias porque estava tentando arrumar.  

Na parte "x<5" tinha substituido por ('A'<=encontrados[x].titulo[0]<='Z')||('a'<=encontrados[x].titulo[0]<='z') porém entrou em loop porque?

5 horas atrás, Jessé P. de Melo disse:

for(int x=0;x<5;x++){ if(encontrados[x].titulo[0]!=0){ printf("\nTitulo: %s\tAutor: %s\tAno: %i\n\n",encontrados[x].titulo,encontrados[x].autor,encontrados[x].ano); }

Segue codigo:

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

void main(void){
    char pesquisar[31]; /*Cria string para pesquisar*/

    struct colecao{    /*Cria estrutura */
        char titulo[31];
        char autor[16];
        int ano;
    };

    struct colecao livros[5]; /*cria um vetor de 5u da estrutura*/
    struct colecao encontrados[5]; /*Vria um outro vetor para copia da pesquisa compativel*/

    for(int x=0;x<5;x++){ /*Inicializa o titulo com 0, ajuda na hora de saber quando parar de imprimir*/
        encontrados[x].titulo[0]='0';
    }

    for(int x=0;x<5;x++){ /*Entrada de dados*/
        printf("Digite o titulo ");
        scanf("%31[^\n]",&livros[x].titulo);
        fflush(stdin);
        printf("Autor: ");
        scanf("%16[^\n]",&livros[x].autor);
        fflush(stdin);
        printf("Ano: ");
        scanf("%i",&livros[x].ano);
        fflush(stdin);
        printf("\n");
    }

    for(;;){ /*loop infinito*/
        printf("Digite um titulo para pesquisar: ");/*Popula variavel da string q esta procurando*/
        scanf("%s",&pesquisar);
        fflush(stdin);
        printf("\n");


        int z=0; /*COntador para saber em qual indice do encontrados copia*/

        for(int x=0;x<5;x++){/*Operação de copia dos titulos encontrados */

            char *ret=NULL;
            ret=strstr(livros[x].titulo,pesquisar);
            if(ret!=0){
                encontrados[z]=livros[x];
                z++;
            }
        }
        for(int x=0;x<5;x++){ /*se o indice do vetor encontrados for uma letra imprime resultado*/
            if((encontrados[x].titulo[0]!='0')){ /*Tenho duvidas se o processo anterior e suficiente então fiz esse redundante*/
                printf("\nTitulo: %s\tAutor: %s\tAno: %i\n\n",encontrados[x].titulo,encontrados[x].autor,encontrados[x].ano);
            }
        }
        for(int x=0;x<5;x++){  /*Limpa o vetor da estrutura encontrados para proxima pesquisa*/
            strcpy(encontrados[x].titulo,"0-");
            strcpy(encontrados[x].autor,"0-");
            encontrados[x].ano=0;
        }
    }
}

 

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante

@Jessé P. de Melo  Olá. Creio q o problema está nessa verificação mesmo. Experimente fazer algo assim:

 

for(int x=0;x<5;x++){ /*se o indice do vetor encontrados for uma letra imprime resultado*/
    if((encontrados[x].titulo != NULL)){ /*Tenho duvidas se o processo anterior e suficiente então fiz esse redundante*/
        printf("\nTitulo: %s\tAutor: %s\tAno: %i\n\n",encontrados[x].titulo,encontrados[x].autor,encontrados[x].ano);
        break; // aqui é para encerrar a busca já q o título foi encontrado
    }

Vê se resolve. Só q a dica q daria é colocar uma condição para o caso do usuário querer parar de pesquisar. Algo como digita -1 por ex. Mas é apenas uma sugestão

adicionado 37 minutos depois

@Jessé P. de Melo Olá. Apenas p melhorar o critério de busca por determinado título:

 

encontrado = 0;
for(int x=0;x<5;x++){ /*se o indice do vetor encontrados for uma letra imprime resultado*/
    if(!strcmp(encontrados[x].titulo, pesquisar)){ /*Tenho duvidas se o processo anterior e suficiente então fiz esse redundante*/
        printf("\nTitulo: %s\tAutor: %s\tAno: %i\n\n",encontrados[x].titulo,encontrados[x].autor,encontrados[x].ano);
        encontrado = 1;
        break;
    }
}
if (!encontrado)
{
    printf("\nNenhum titulo encontrado!\n\n");
    // colocar aqui o q deseja caso não seja encontrado nada                  
}

Se deu p ajudar poste o resultado, caso contrário poste se inda está dando erro. Para dar a resposta  pequei por base seu comentário:

 

3 horas atrás, Jessé P. de Melo disse:

hum...Realmente continuou dando o mesmo problema.

Então o erro ta aqui...

7 horas atrás, Jessé P. de Melo disse:

for(int x=0;x<5;x++){ if(encontrados[x].titulo[0]!=0){ printf("\nTitulo: %s\tAutor: %s\tAno: %i\n\n",encontrados[x].titulo,encontrados[x].autor,encontrados[x].ano); }

Em vez de comparar com 0 vou comparar com as letras do alfabeto.

 

Se estou correto com o critério q usei p fornecer a resposta avisa

Mas na busca q você estava fazendo era procurando pelo índice 0 do título. Era esse o problema. Penso eu

Também gostaria de frisar q é uma boa prática d programação inicializar um ponteiro com o valor "NULL". Dessa forma seu ponteiro deixa d ser um "ponteiro selvagem", q pode apontar p qualquer lugar

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

10 horas atrás, Jessé P. de Melo disse:

for(int x=0;x<5;x++){ 
  if(encontrados[x].titulo[0]!=0){ 
    printf("\nTitulo: %s\tAutor: %s\tAno: %i\n\n",
           			encontrados[x].titulo,encontrados[x].autor,encontrados[x].ano);
  }

 

Aqui nada tem de ponteiros, o que temos é um comparação de tipos int com char, neste ponto:

encontrados[x].titulo[0]!=0

Qual é a sua intenção? E Você já se perguntou para que serve a variável z no algoritmo

      for(int x=0;x<5;x++){/*Operação de copia dos titulos encontrados */

            char *ret=NULL;
            ret=strstr(livros[x].titulo,pesquisar);
            if(ret!=0){
                encontrados[z]=livros[x];
                z++;
            }

Eu já sei a resposta para seu problema, vou esperar você a perceber também.

 

  • Aparte do algoritmo /*Operação de copia dos titulos encontrados */ está totalmente correta.
  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde. Desculpe pela dmr ! As festividades e atrapalharam os estudos do fds.

Em 12/05/2018 às 00:07, AnsiC disse:

Qual é a sua intenção? E Você já se perguntou para que serve a variável z no algoritmo

A variável Z serve para indicar o índice do vetor copia.

 

Tenho uma boa e má noticia.

A boa noticia é que arrumei o código e está funcionando...

A má noticia é que não sei exatamente como ! :confused:

Acho que arrumei sábado quando vocês me responderam, mas por estar pilhado eu não compilei só arrumei salvei e fechei. :tantan:

Segue script:

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

void main(void){
    char pesquisar[31]; /*Cria string para pesquisar*/

    struct colecao{    /*Cria estrutura */
        char titulo[31];
        char autor[16];
        int ano;
    };

    struct colecao livros[5]; /*cria um vetor de 5u da estrutura*/
    struct colecao encontrados[5]; /*Vria um outro vetor para copia da pesquisa compativel*/

    for(int x=0;x<5;x++){ /*Inicializa o titulo com 0, ajuda na hora de saber quando parar de imprimir*/
        encontrados[x].titulo[0]='0';
    }

    for(int x=0;x<5;x++){ /*Entrada de dados*/
        printf("Digite o titulo ");
        scanf("%31[^\n]",&livros[x].titulo);
        fflush(stdin);
        printf("Autor: ");
        scanf("%16[^\n]",&livros[x].autor);
        fflush(stdin);
        printf("Ano: ");
        scanf("%i",&livros[x].ano);
        fflush(stdin);
        printf("\n");
    }

    for(;;){ /*loop infinito*/
        printf("Digite um titulo para pesquisar: ");/*Popula variavel da string q esta procurando*/
        scanf("%s",&pesquisar);
        fflush(stdin);
        printf("\n");


        int z=0; /*COntador para saber em qual indice do encontrados copia*/

        for(int x=0;x<5;x++){/*Operação de copia dos titulos encontrados */

            char *ret=NULL;
            ret=strstr(livros[x].titulo,pesquisar);
            if(ret!=0){
                encontrados[z]=livros[x];
                z++;
            }
        }
        for(int x=0;x<5;x++){ /*se o indice do vetor encontrados for uma letra imprime resultado*/
            if((encontrados[x].titulo[0]!='0')){ /*Tenho duvidas se o processo anterior e suficiente então fiz esse redundante*/
                printf("\nTitulo: %s\tAutor: %s\tAno: %i\n\n",encontrados[x].titulo,encontrados[x].autor,encontrados[x].ano);
            }
        }
        for(int x=0;x<5;x++){  /*Limpa o vetor da estrutura encontrados para proxima pesquisa*/
            strcpy(encontrados[x].titulo,"0-");
            strcpy(encontrados[x].autor,"0-");
            encontrados[x].ano=0;
        }
    }
}

A saída está poluída porque não me familiarizei com comando cls

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então pois somente restava fazer como abaixo:

        int z=0; /*COntador para saber em qual indice do encontrados copia*/

        for(int x=0;x<5;x++){/*Operação de copia dos titulos encontrados */

            char *ret=NULL;
            ret=strstr(livros[x].titulo,pesquisar);
            if(ret!=0){
                encontrados[z]=livros[x];
                z++;
            }
        }
        for(int x=0;x<z;x++){ /*se o indice do vetor encontrados for uma letra imprime resultado*/
            if((encontrados[x].titulo[0]!='\0')){ /*Tenho duvidas se o processo anterior e suficiente então fiz esse redundante*/
                printf("\nTitulo: %s\tAutor: %s\tAno: %i\n\n",encontrados[x].titulo,encontrados[x].autor,encontrados[x].ano);
            }
        }

colocar o z, pois z é numero de ocorrências então imprimir z elementos.

  • Curtir 1

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

×