CS50 Caesar Cipher fornecendo saída incorreta (pset2)
Estou tentando implementar um programa que criptografa mensagens usando a cifra de César. Eu tenho algum tipo de erro lógico em meu código e estou puxando meu cabelo tentando encontrá-lo. A lógica faz sentido para mim, mas continuo obtendo a saída errada. Por favor, alguém pode me orientar com esse problema!
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
//Check that program was run with one command-line argument
if (argc == 2)
{
int n = strlen(argv[1]);
//Iterate over the provided argument to make sure all characters are digits
for (int i = 0; i < n; i++) {
if (isdigit(argv[1][i])) {
//Convert that command-line argument from a string to an int
// int key = atoi(argv[1]);
int key = atoi(argv[1]);
//Prompt user for plaintext
string plaintext = get_string("Enter plain text: ");
printf("ciphertext: ");
//int l = strlen(plaintext);
//Iterate over each character of the plaintext:
for (int j = 0, l=strlen(plaintext); j < l; j++) {
if (isalpha(plaintext[j])) {
if (isupper(plaintext[j])) {
printf("%c", (((plaintext[i] - 65) + key) % 26) + 65);
}
if (islower(plaintext[j])) {
printf("%c", (((plaintext[i] - 97) + key) % 26) + 97);
}
}
else
{
printf("%c", plaintext[i] );
}
}
printf("\n");
return 0;
}
else {
printf("Usage: ./caesar key\n");
return 1;
}
}
}
else
{
printf("Usage: ./caesar key\n");
return 1;
}
}
Respostas
O código que executa a criptografia não deve estar dentro do loop que verifica se todos os caracteres argv[1]são dígitos. Primeiro faça o loop que valida a chave. Se for bem-sucedido, pergunte ao texto simples e execute a criptografia.
O principal erro lógico é que você tem plaintext[i]vários lugares. Isso deveria ser plaintext[j].
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
//Check that program was run with one command-line argument
if (argc == 2)
{
int n = strlen(argv[1]);
//Iterate over the provided argument to make sure all characters are digits
for (int i = 0; i < n; i++) {
if (!isdigit(argv[1][i])) {
printf("Error: Key must be numeric");
return 1;
}
}
//Convert that command-line argument from a string to an int
int key = atoi(argv[1]);
//Prompt user for plaintext
string plaintext = get_string("Enter plain text: ");
printf("ciphertext: ");
//Iterate over each character of the plaintext:
for (int j = 0, l=strlen(plaintext); j < l; j++) {
if (isupper(plaintext[j])) {
printf("%c", (((plaintext[j] - 'A') + key) % 26) + 'A');
} else if (islower(plaintext[j])) {
printf("%c", (((plaintext[j] - 'a') + key) % 26) + 'a');
} else {
printf("%c", plaintext[j] );
}
}
printf("\n");
return 0;
} else {
printf("Usage: ./caesar key\n");
return 1;
}
}
Também não há necessidade de aninhar as verificações isupper()e islower()dentro isalpha(). Use apenas else ifpara testar as 3 condições mutuamente exclusivas: letra maiúscula, letra minúscula, tudo o mais.
E evite códigos ASCII embutidos, use literais de caracteres.