为什么我的代码在通过凯撒密码移动字母时会跳过空格和标点符号?

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

所以我的 caesar 编程代码可以很好地用键移动字母,但不会保留空格或标点符号。例如,如果用户在命令行中使用 ./caesar 2 运行程序,并且他们想要“A b”。要移动,结果显示为“Cd”,但它应该是“C d.”。我试图解决这个问题,但我不知道如何解决。任何帮助,将不胜感激。我的代码如下。

#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");
   }

}

你的循环基本上是这样的:

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

所以当字符是字母时你做一个转换。但如果不是,你什么都不做。这就是为什么您在输出中看不到除字母以外的任何内容。

您需要在此处添加一个 else 子句,以便在不是字母的情况下简单地打印给定的内容。

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

isalpha 排除空格和标点符号。

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

如果字符不是字母顺序,测试 if(isalpha(plain[i])) 不会执行任何其他操作,因此会被忽略。

您可以删除它并在下面添加 else printf("%c", plain[i]);,这样部分代码看起来像这样

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");