CS50 Caesar Cipher dando salida incorrecta (pset2)

Aug 24 2020

Estoy tratando de implementar un programa que encripta mensajes usando el cifrado de Caesar. Tengo algún tipo de error lógico en mi código, y me he estado tirando del pelo tratando de encontrarlo. La lógica tiene sentido para mí, pero sigo obteniendo el resultado incorrecto. ¡Alguien puede guiarme con este 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;
    }

}

Respuestas

2 Barmar Aug 24 2020 at 20:46

El código que realiza el cifrado no debe estar dentro del bucle que verifica que todos los caracteres argv[1]sean dígitos. Primero haz el ciclo que valida la clave. Si tiene éxito, pregunte el texto sin formato y realice el cifrado.

El mayor error lógico es que lo tienes plaintext[i]en varios lugares. Eso debería 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;
    }
}

Tampoco es necesario anidar los cheques isupper()y en el islower()interior isalpha(). Solo use else ifpara probar las 3 condiciones mutuamente excluyentes: letra mayúscula, letra minúscula, todo lo demás.

Y evite los códigos ASCII de codificación rígida, use literales de caracteres.