Ir ao conteúdo
  • Cadastre-se

C Programa cifragem pelo método de César -- Problema com comparação de espaços


Abel Castro

Posts recomendados

Eu estou implementando um programa para encriptar/decriptar uma mensagem através do método de César ou cifra de César.. 
A princípio o código funciona, porém estou tendo problemas quando o usuário digita uma mensagem com espaços.

 

Aqui está o código:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define tamanho 500
void limpar_tela();
int pega_mensagemEchave(int op, int chave, char* mensagem);
void aplicaMetodo_mensagem(int op, int chave, char* mensagem);

void limpar_tela(){
	system("clear || cls");
}
int pega_mensagemEchave(int op, int chave, char* mensagem){
	switch(op){
		case 1:
			printf("\n\nDIGITE A MENSAGEM QUE DESEJA CIFRAR: ");
			break;
		case 2:
			printf("\n\nDIGITE A MENSAGEM QUE DESEJA DECIFRAR: ");
			break;
	}
	fflush(stdin);
	scanf("%[^\n]", mensagem);//PEGA TUDO O QUE VEM ANTES DO ENTER(\n) E ARMAZENA NA VARIÁVEL mensagem;
	fflush(stdin);
	printf("\n\nDIGITE A QUANTIA DE LETRAS DESLOCADAS: ");
	scanf("%d", &chave);
	return chave;
}
void aplicaMetodo_mensagem(int op, int chave, char* mensagem){
	int i, tamanho_texto= strlen(mensagem); //O TAMANHO DO TEXTO É DEFINIDO COM A FUNÇÃO strlen DA BIBLIOTECA string.h;

	printf("%d", chave);
	//LOOP DO COMEÇO DO VETOR ATÉ O FINAL DELE;
	for(i= 0; i< tamanho_texto; i++){
		switch(op){
			case 1:
				mensagem[i]+= chave;
				//CASO A LETRA+CHAVE SEJA UM ESPAÇO, O VETOR RECEBE O PRÓPRIO ESPAÇO;
				if(mensagem[i]== 32){
					mensagem[i]= 32;
				//CASO A LETRA+CHAVE PASSE DE 'Z' E SEJA MENOR QUE 'z' OU APENAS SEJA MAIOR QUE 'z', A CONTAGEM REINICIA NO COMEÇO DO ALFABETO;
				}else if((mensagem[i]> 90 && mensagem[i]< 97) || mensagem[i]> 122){
					mensagem[i]-= 26;
				}
				break;
			case 2:
				mensagem[i]-= chave;
				//CASO A LETRA+CHAVE SEJA UM ESPAÇO, O VETOR RECEBE O PRÓPRIO ESPAÇO;
				if(mensagem[i]== 32){
					mensagem[i]= 32;
				//CASO A LETRA-CHAVE NAO CHEGUE EM 'a' OU NAO CHEGUE EM 'A', A CONTAGEM VAI PRO FINAL DO ALFABETO;
				}else if(mensagem[i]< 65 || (mensagem[i]< 97 && mensagem[i]> 90)){
					mensagem[i]+= 26;
				}
				break;	
		}	
	}
}
int main(){
	int chave, op, continuar;
	char mensagem[tamanho];

	//LOOP PRINCIPAL PARA RODAR NOVAMENTE SE DIGITAR 'S';
	do{
		limpar_tela();
		printf("\n\n\n\t\t\t\t\t\t\t%c DECIFRADOR/CIFRADOR DE C%cDIGOS DE ACORDO COM O SISTEMA CESAR %c\n\n\nO QUE DESEJA FAZER?\n\n1- CIFRAR UMA MENSAGEM.\n2- DECIFRAR UMA MENSAGEM.\n0- SAIR.\n", 179, 224, 179);
		scanf("%d", &op);
		if(op> 0){
			limpar_tela();
			chave= pega_mensagemEchave(op, chave, mensagem);
			aplicaMetodo_mensagem(op, chave, mensagem);
			switch(op){
				case 1:
					printf("\nMENSAGEM CIFRADA:\n%s", mensagem);
					break;
				case 2:
					printf("\nMENSAGEM DECIFRADA:\n%s", mensagem);
					break;
			}
		}else{			
			break;
		}
		printf("\n\n\n\nDESEJA DECIFRAR/CIFRAR NOVAMENTE?\n\nTECLE 'S' PARA UTILIZAR O PROGRAMA NOVAMENTE.\nTECLE 'ENTER' PARA SAIR.\n");
		fflush(stdin);
		scanf("%c", &continuar);
		fflush(stdin);
	}while(continuar== 's' || continuar== 'S');
	limpar_tela();
	return 0;
}

Eu tentei fazer uma comparação com o valor decimal do espaço segundo a tabela ASCII, mas não sei por qual motivo eu não to conseguindo que o printf seja um espaço assim como a entrada..

Se alguém puder dar uma lida e me ajudar, agradeço.. Valeu :) 

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

@Abel Castro    o caractere espaço é esse mesmo 32 ,  mas o que você precisa fazer é modificar algumas linhas da função aplicaMetodo_mensagem   que ficaria assim :

for(i= 0; i< tamanho_texto; i++){
    switch(op){
        case 1:
            a=mensagem[i];
            a+= chave;
            /*//CASO A LETRA+CHAVE SEJA UM ESPAÇO, O VETOR RECEBE O PRÓPRIO ESPAÇO;*/
            if(mensagem[i]== 32){
                a=32;
                /*//CASO A LETRA+CHAVE PASSE DE 'Z' E SEJA MENOR QUE 'z' OU APENAS SEJA MAIOR QUE 'z', A CONTAGEM REINICIA NO COMEÇO DO ALFABETO;*/
            }else if((mensagem[i]> 90 && mensagem[i]< 97) || mensagem[i]> 122){
                a=mensagem[i];
                a-= 26;
            }
            mensagem[i]=a;
            break;
        case 2:
            a=mensagem[i];
            a-= chave;
            /*//CASO A LETRA+CHAVE SEJA UM ESPAÇO, O VETOR RECEBE O PRÓPRIO ESPAÇO;*/
            if(mensagem[i]== 32){
                a= 32;
                /*//CASO A LETRA-CHAVE NAO CHEGUE EM 'a' OU NAO CHEGUE EM 'A', A CONTAGEM VAI PRO FINAL DO ALFABETO;*/
            }else if(mensagem[i]< 65 || (mensagem[i]< 97 && mensagem[i]> 90)){
                a=mensagem[i];
                a+= 26;
            }
            mensagem[i]=a;
            break;
    }
}

mas para decifrar você precisa ter uma mensagem que tenha sido cifrada antes aí então decifra,  então para isso você precisaria guardar essa mensagem que foi cifrada e depois na hora de decifrar você pega essa mesma mensagem .

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

Vou deixar aqui uma solução de um professor meu, assim como todo aluno de ciência da computação, fiz com IFS e IFS.

Coloquei o código acreditando que você vai estudá-lo e não apenas dar Ctrl-c. Implemente do seu modo antes e depois estude o que foi feito pelo meu professor.

 

int cesarCIF(char s[])
{
    int i;

    for (i = 0; s[i]; i++) {
        s[i] = 'A' + ((s[i] - 'A' + 3) % 26);
        /* Achou estranho?
         * Aposto que você fez um montão de ifs aqui, não?
         *
         * Vamos a lógica.
         * Se s[i] for 'E' deve virar 'H' certo?
         * 'E' == 69 em decimal
         * Dentro do parentes  tem s[i] - 'A' + 3
         * Para o caso do 'E' dá 'E' - 'A' = 4 (69 - 65)
         * Somando ao 3 dá 7. 7%26 = 7
         * s[i] = 'A' + 7 = 72 (e 72 é o 'H' da tabela ascii)
         *
         * Agora outro exemplo: s[i]='X' Neste caso deve virar 'A'
         *
         * 'A' + (('X' - 'A' + 3 )%26)
         * 'A' + (( 23 + 3) %26)   ==> 'X'(88) - 'A'(65) == 23
         * 'A' + (26%26) => o resto de 26 dividido por 26 é ZERO
         * 'A' + 0 = 'A'
         * */
    }
    return (i);                 // retorna tamanho de s, que é a quantidade de cars cifrados
}

/* Observou que o cesarCIF tem apenas quatro linhas de código? */

 

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

1 minuto atrás, Abel Castro disse:

Que solução mais compacta! Eu nunca conseguiria pensar em uma expressão como essa pra resolver esse tipo de problema rsrs. Gostaria de saber o nome desse seu professor..

Agradeço por compartilhar esse código, @Chrissy Costanza  :)

http://gravatai.ulbra.tche.br/~elgio/ulbra/

https://www.vivaolinux.com.br/~elgio

  • Curtir 1
  • Obrigado 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...