Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
giovany93

C Alocação dinamica e ponteiro

Recommended Posts

Eu estou tentando fazer um código em c no qual uma palavra deve ser criptografada.Eu não sei o que está dando errado.

#include<stdlib.h>
#include<string.h>
int main()
{
    int n;

    printf("DIGITE O TAMANHO DA PALAVRA...\n");
    scanf("%d",&n);
    char *p;
    p=(char*) malloc(n*sizeof(char));//aloco o valor digitado
scanf("%s",p);//armazeno na variável
printf(" %s",*p);//imprimo a palavra normalmente
    criptografia(*p,n);
}
void criptografia(char palavra[ ],int n)
{
    int i;
    for(i=0; i<n; i++)
    {
        switch(palavra)
        {
        case 'A':palavra='J';
        case 'B':palavra='K';
        case 'C':palavra='L';
        case 'D':palavra='M';
        case 'E':palavra='N';
        case 'F':palavra='O';
        case 'G':palavra='P';
        case 'H':palavra='Q';
        case 'I':palavra='R';
        case 'J':palavra='S';
        case 'K':palavra='T';
        case 'L':palavra='U';
        case 'M':palavra='W';
        case 'N':palavra='X';
        case 'O':palavra='Y';
        case 'P':palavra='Z';
        case 'Q':palavra='A';
        case 'R':palavra='B';
        case 'S':palavra='C';
        case 'T':palavra='D';
        case 'U':palavra='E';
        case 'V':palavra='F';
        case 'W':palavra='G';
        case 'X':palavra='H';
        case 'Y':palavra='I';
        case 'Z':palavra='J';

        }
    printf("%s",palavra);
    }

}

Compartilhar este post


Link para o post
Compartilhar em outros sites

São alguns erros de sintaxe, principal é quando queremos acessar o endereço que é o "valor dentro de um ponteiro" usamos o nome do ponteiro sem asterisco. Mas quando queremos acessar o valor que está dentro do endereço "que é o valor de um ponteiro" usamos  asterisco. Com relação aos outros erros, são todos alertados pelo compilador. Assim com as devidas correções o seu programa fica assim:

#include  <stdio.h>  /**< inclui as funções padrões de entrada e saída. */ 
#include <stdlib.h>  /**< inlcui as funções manipuladoras de memória. */
#include <string.h>  /**< inclui as funções manipuladoras de strings. */

void criptografia (char palavra[], int n);

int main(int argc, char **argv){
    int n;
    printf ("DIGITE O TAMANHO DA PALAVRA...\n");
    scanf ("%d", &n);

    char *p;
    p =  (char*) malloc (n * sizeof(char) + 1);  /* aloco o valor digitado */
    scanf ("%s", p);  /* armazeno na variável */
    
    printf("original :: %s\n", p);  /* imprimo a palavra normalmente */

    criptografia (p, n);

    /* boa prática: limpe o contéudo, libere memória sem uso. */
    char *limit =  p - 1;
    p +=  n;
    while (limit  <--  p){ *p =  0; }
    
    free (p); 
 
    return  0; }


void criptografia (char palavra[], int n){
    int i;
    for (i =  0; i  <  n; i ++){
        switch (palavra[i]){
            case 'A':palavra[i] =  'J'; break;
            case 'B':palavra[i] =  'K'; break;
            case 'C':palavra[i] =  'L'; break;
            case 'D':palavra[i] =  'M'; break;
            case 'E':palavra[i] =  'N'; break;
            case 'F':palavra[i] =  'O'; break;
            case 'G':palavra[i] =  'P'; break;
            case 'H':palavra[i] =  'Q'; break;
            case 'I':palavra[i] =  'R'; break;
            case 'J':palavra[i] =  'S'; break;
            case 'K':palavra[i] =  'T'; break;
            case 'L':palavra[i] =  'U'; break;
            case 'M':palavra[i] =  'W'; break;
            case 'N':palavra[i] =  'X'; break;
            case 'O':palavra[i] =  'Y'; break;
            case 'P':palavra[i] =  'Z'; break;
            case 'Q':palavra[i] =  'A'; break;
            case 'R':palavra[i] =  'B'; break;
            case 'S':palavra[i] =  'C'; break;
            case 'T':palavra[i] =  'D'; break;
            case 'U':palavra[i] =  'E'; break;
            case 'V':palavra[i] =  'F'; break;
            case 'W':palavra[i] =  'G'; break;
            case 'X':palavra[i] =  'H'; break;
            case 'Y':palavra[i] =  'I'; break;
            case 'Z':palavra[i] =  'J'; break; }}

    printf ("criptografado :: %s\n", palavra);

    return  ; }

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ah sim , Eh verdade o ponteiro pode ser visto como vetor né? aih eu não preciso e nem posso fazer scanf("%s",*p);

Outra coisa você sabe me dizer porque quando digito a palavra (sem digitar o tamanho),o código não dah erro ?Por exemplo:

No código tá assim:

printf ("DIGITE O TAMANHO DA PALAVRA...\n"); scanf ("%d", &n);

mas se eu digitar qualquer palavra , o codigo já imprime a criptografia e a palavra normal ,porque não dah erro?

Queria saber mais coisa ainda...Aqui você aloca n+1 por causa do caracter do fim de string né? Se sim porque você não preenche a palavra?Ela eh automaticamente preenchida?

char *p; p = (char*) malloc (n * sizeof(char) + 1); /* aloco o valor digitado */ scanf ("%s", p); /* armazeno na variável */ printf("original :: %s\n", p); /* imprimo a palavra normalmente */ criptografia (p, n);

 

E aqui embaixo eu não entendi ,é que eu  sou "calouro em C"kkk.A função free já não faz essa limpeza.Me explique pfv ,pois eu não entendi o while nem char *limit = p - 1; p += n.Desde já agradeço!!!

 

/* boa prática: limpe o contéudo, libere memória sem uso. */ char *limit = p - 1; p += n; while (limit <-- p){ *p = 0; } free (p); return 0; }

Compartilhar este post


Link para o post
Compartilhar em outros sites
20 minutos atrás, giovany93 disse:

Ah sim , Eh verdade o ponteiro pode ser visto como vetor né? aih eu não preciso e nem posso fazer scanf("%s",*p);

Sim.

 

21 minutos atrás, giovany93 disse:

Outra coisa você sabe me dizer porque quando digito a palavra (sem digitar o tamanho),o código não dah erro ?Por exemplo:

No código tá assim:

printf ("DIGITE O TAMANHO DA PALAVRA...\n"); scanf ("%d", &n);

mas se eu digitar qualquer palavra , o codigo já imprime a criptografia e a palavra normal ,porque não dah erro?

O espaço da memória que foi alocada para a variável n foi usado por outros programas anteriormente, logo provavelmente já existe um valor nesse espaço de memória, quando você digitou a palavra diretamente ao invés de um número a leitura do scanf falhou, e nenhum valor foi guardado na variável n, o que também significa que o valor que já estava lá não foi modificado.

 

Se esse valor for um número positivo grande o suficiente o seu programa vai funcionar, pois usa esse número para alocar a memória dinamicamente (como não se sabe o quão grande é o número possivelmente uma grande quantidade de memória é alocada), e o processo de criptografia funciona normalmente trabalhando nesse espaço de memória alocado. (Para evitar isso precisaria checar o retorno da função scanf para verificar se teve sucesso na leitura dos dados, e tomar decisões de acordo com o retorno.)

 

31 minutos atrás, giovany93 disse:

Queria saber mais coisa ainda...Aqui você aloca n+1 por causa do caracter do fim de string né? Se sim porque você não preenche a palavra?Ela eh automaticamente preenchida?

char *p; p = (char*) malloc (n * sizeof(char) + 1); /* aloco o valor digitado */ scanf ("%s", p); /* armazeno na variável */ printf("original :: %s\n", p); /* imprimo a palavra normalmente */ criptografia (p, n);

Sim, toda string em C acaba em um caractere nulo '\0', indicando onde a string acaba, logo o vetor de char deve ter pelo menos 1 posição a mais que o número de caracteres da string para poder armazenar o caractere nulo.

Mas não entendi sua dúvida, o que quer dizer com "porque você não preenche a palavra?" ? A palavra é fornecida pelo usuário no scanf("%s", p); .

 

36 minutos atrás, giovany93 disse:

E aqui embaixo eu não entendi ,é que eu  sou "calouro em C"kkk.A função free já não faz essa limpeza.Me explique pfv ,pois eu não entendi o while nem char *limit = p - 1; p += n.Desde já agradeço!!!

 

/* boa prática: limpe o contéudo, libere memória sem uso. */ char *limit = p - 1; p += n; while (limit <-- p){ *p = 0; } free (p); return 0; }

Sim, free() libera a memória, os valores continuam lá mas agora o espaço da memória pode ser usado para outras coisas e esses valores serão sobrepostos/substituídos. Nessa parte ele está zerando todas as posições da memória antes de desalocar a memória, mas também não entendi o porque isso seria necessário.

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, giovany93 disse:

E aqui embaixo eu não entendi ,é que eu  sou "calouro em C"kkk.A função free já não faz essa limpeza.Me explique pfv ,pois eu não entendi o while nem char *limit = p - 1; p += n.Desde já agradeço!!!

Certamente, a função desaloca a memória que foi alocada anteriormente, mas não faz a limpeza de seu conteúdo. Essa limpeza extra de seus valores antes de desalocar vai custar um pouco de desempenho do seu programa, que no contexto literalmente não significa nada, mais literalmente coletou-se o lixo com certeza.

 

 

 

 

 

19 minutos atrás, isrnick disse:

mas também não entendi o porque isso seria necessário.

Também quem lhe disse que é necessário. Você tem todo direito de não considera-la, mais não deve também distorce-la. E obrigado pelo restante!

Editado por AnsiC
Correção

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas não entendi sua dúvida, o que quer dizer com "porque você não preenche a palavra?" ? A palavra é fornecida pelo usuário no scanf("%s", p);  Eu quero dizer se o caractere de fim de string é preenchido sozinho ou devemos fazer com que seja atribuída a última posição o '\0'.Outra coisa,eu entendei que a função limpa o espaço para depois desalocar,mas não entendi o código.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em 15/08/2018 às 12:45, giovany93 disse:

Eu quero dizer se o caractere de fim de string é preenchido sozinho ou devemos fazer com que seja atribuída a última posição o '\0'.

Entendi.

 

Funções de leitura de string sempre colocam o '\0' após os caracteres de string automaticamente, não precisa fazer manualmente (certifique-se de que o vetor de caracteres que vai armazenar a string sempre seja grande o suficiente para armazenar todos os caracteres da string mais o caractere nulo '\0').

 

Obs: No caso do fgets() ele captura até o caractere nova linha '\n' que é digitado pelo usuário quando ele aperta Enter, então costuma-se remover manualmente esse caractere substituindo-o pelo caractere nulo '\0'.

 

Em 15/08/2018 às 12:45, giovany93 disse:

Outra coisa,eu entendei que a função limpa o espaço para depois desalocar,mas não entendi o código.

Funciona assim:

//Cria um ponteiro que aponta para uma posição de
//memória antes da posição apontada pelo ponteiro p:
char *limit =  p - 1;

//Faz p apontar para a posição final do vetor:
p +=  n;

//Vai decrementando 1 de p, e enquanto p for
//maior que a posição limite, coloca valor 0
//na posição do vetor.
while (limit  < --p){
    *p =  0;
}

free (p);

 

 

Mas @AnsiC agora que prestei atenção nesse código tem um problema pois p acaba com valor igual ao valor de limit, que é igual a p original menos 1, então free(p) vai estar liberando o lugar errado da memória. Certo?

  • Curtir 2

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






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

×