简体   繁体   中英

Why is my code skipping over spaces and punctuation when shifting letters through the caesar cipher?

So my code for my caesar programming is shifting the letters with the key just fine, but it is not keeping the spaces or puncuation. For example, if the user runs the program using./caesar 2 in the command line, and they want "A b." to be shifted, the result comes out as "Cd", but it should be "C d.". I have tried to fix the problem but I just don't know how. Any help would be appreciated. My code is below.

#include <stdio.h>
#include <cs50.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, string argv[])
{

   string plain = NULL;
   char num1;
   char halftotal;
   char total;
   
   //creating the key

   if(argc == 2)
   {
       int shift = atoi(argv[1]);
       if(shift < 0)
         {
            printf("Usage: ./caesar key\n");

            return 1;
         }
         else if(shift > 0)
         {
            //prompting for plaintext

       plain = get_string("Plaintext: ");

       //enciphering plaintext

       int test = strlen(plain);
      printf ("Ciphertext: ");
       for( int i = 0;i < test;i++)
         {
           if(isalpha(plain[i]))
               {
                  if(isupper(plain[i]))
                  {
                      num1 =  plain[i] - 65;
                      halftotal = (num1 + shift)%26;
                      total = (halftotal + 65);\
                      printf("%c", total);
                  }
                  else if(islower(plain[i]))
                  {
                      num1 =  plain[i] - 97;
                      halftotal = (num1 + shift)%26;
                      total = (halftotal + 97);
                      printf("%c", total);
                  }

               }
         }
         printf("\n");

         return 0;
         }

   }
   else if(argc != 2)
   {
      printf("Usage: ./caesar key\n");
   }

}

Your loop basically looks like this:

   for( int i = 0;i < test;i++)
     {
       if(isalpha(plain[i]))
           {
               // convert the character
               ...
           }
     }

So when the character is a letter you do a conversion. But if it's not, you do nothing. That's why you don't see anything other than letters in the output.

You need to add an else clause here to simply print whatever was given if it's not a letter.

   for( int i = 0;i < test;i++)
     {
       if(isalpha(plain[i]))
           {
               // convert the character
               ...
           }
       else
       {
           printf("%c", plain[i]);
       }
     }

isalpha exludes whitespace and punctuation characters.

http://cplusplus.com/reference/cctype/isalpha/

The test if(isalpha(plain[i])) doesn't do anything else if the character is not alphabetical, so it is ignored.

You can remove that and add else printf("%c", plain[i]); below so that part of the code looks like this

printf ("Ciphertext: ");
for( int i = 0;i < test;i++) 
{
    if(isupper(plain[i]))
    {
        num1 =  plain[i] - 'A';         // replaced magic numbers too       
        halftotal = (num1 + shift) % 26;
        total = (halftotal + 'A');
        printf("%c", total);
    }
    else if(islower(plain[i]))
    {
        num1 =  plain[i] - 'a';
        halftotal = (num1 + shift) % 26;
        total = (halftotal + 'a');
        printf("%c", total);
    }
    else 
    {
        printf("%c", plain[i]);
    }
}
printf("\n");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM