【问题标题】:Caesar Cipher Program to Encrypt/Decrypt a paragraph用于加密/解密段落的凯撒密码程序
【发布时间】:2018-02-17 04:59:51
【问题描述】:

首先,我是编程新手,所以要温柔。此外,我一直在努力完成这项任务,但无济于事。任务是创建一个凯撒密码程序,该程序可以加密或解密最多 100 个字符的段落。它实际上是两个独立的实验室。第一个实验室是加密,然后第二个实验室是解密。一旦我弄清楚如何创建加密程序,解密程序应该很简单,因为我可以对解密而不是加密进行语义更改。无论如何,这是我到目前为止的代码。它通过了他们给我们的 5 个测试中的 4 个,但由于某种原因,有一个测试的最后一个字符是“@”符号。这对我来说毫无意义,因为它在任何其他测试中都不会发生,并且我相信我的代码在字符串的 '\0' 符号处放置了一个符号,因此'@'不应该出现在这个测试中。

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

// ---------------------- DO NOT MODIFY THIS SECTION -----------------------    ---------
#define MAX_PGRAPH_LENGTH 100
#define MAX_WORD_LENGHT 20

int main(void) {   
// definitions
char plaintext[MAX_PGRAPH_LENGTH] = "";
char ciphertext[MAX_PGRAPH_LENGTH];
char input[MAX_WORD_LENGHT];    

// read the key
int key;
scanf("Key: %d, ", &key);

// read text
scanf("Input: ");
while (true)
{
    scanf("%s", input);
    if (strlen(plaintext) + strlen(input) + 1 > MAX_PGRAPH_LENGTH)
        break;

    strcat(plaintext, input);
    strcat(plaintext, " ");
}
plaintext[strlen(plaintext) - 1] = '\0';
// ---------------------- --------------------------------------------------    ---------




int i;

for(i = 0; i < strlen(plaintext); ++i) 
{

  if(plaintext[i] >= 'a' && plaintext[i] <= 'z') {
     ciphertext[i] = ((plaintext[i] + (key % 26) - 97) % 26) + 97; 

     if(ciphertext[i] > 'z') {
        ciphertext[i] = ((plaintext[i] + (key % 26) - 97) % 26) + 97 - 26; }
  }


  else if(plaintext[i] >= 'A' && plaintext[i] <= 'Z') {
     ciphertext[i] = ((plaintext[i] + (key % 26) - 'A') % 26) + 'A';

     if(ciphertext[i] > 'Z') {
        ciphertext[i] = ((plaintext[i] + (key % 26) - 'A') % 26) + 'A' - 26; }
  }

  else {
     ciphertext[i] = plaintext[i]; }

}
 for(i = 0; i < strlen(plaintext) && plaintext[i] == '\0'; ++i) {
  ciphertext[i] = '\0'; }



// ---------------------- DO NOT MODIFY THIS SECTION -----------------------    ---------
printf("   Key: %d\n", key);
printf(" Input: %s\n", plaintext); 
printf("Output: %s\n", ciphertext);
// ---------------------- --------------------------------------------------    ---------
}

如您所见,实验室为我们提供了设置和多个代码块,而我负责编码的实际凯撒密码部分。我的问题是,我没有在 C 的最后一个位置正确设置 '\0' 吗?我还注意到的一件事是,如果我输入诸如“狗跑”之类的输入,当输入打印到屏幕上时,它将打印“狗跑跑跑跑......”直到它达到 100 个字符。幸运的是,他们给我们运行的所有测试都是超过 100 个字符的段落,所以我实际上不必担心通过我加密少于 100 个字符的测试。但我仍然想知道为什么我的明文字符串一遍又一遍地重复最后一个输入单词。抱歉,这篇文章太长了,我已经尝试了所有方法,但不知道我哪里出错了。

【问题讨论】:

  • 您使用的语言的标签可能会有所帮助。作为新用户,您还应该至少阅读tour 一段时间。

标签: c caesar-cipher


【解决方案1】:

它重复最后一个单词,因为你没有退出无限循环。

while (true)
{
    scanf("%s", input);
    if (strlen(plaintext) + strlen(input) + 1 > MAX_PGRAPH_LENGTH)
        break;

    strcat(plaintext, input);
    strcat(plaintext, " ");
}

退出循环的唯一方法是执行break 语句,这只有在inputplaintext 的总长度大于MAX_PGRAPH_LENGTH 时才有可能。之所以只重复最后一个单词,是因为scanf() 很可能会逐字读取输入。

另外,你没有通过带有@字符的测试用例的原因可能是因为字母字符以十进制65开头(对应于A),而@的十进制值为64。 @ 是 1 并且在我看来,使用 @ 测试用例失败的代码并不是巧合。因此,我认为您应该仔细检查算术运算并跟踪示例输入的代码。

【讨论】:

  • 啊,谢谢你,我会仔细检查我的算术以确定。
【解决方案2】:

重复出现在提供的代码中...而不是在您的代码中。

阅读下一个单词(永远),直到达到最大段落长度。 如果没有下一个单词,输入的值不会更新,只是重复,直到总长度达到MAX_PGRAPH_LENGTH

while (true)
{
    scanf("%s", input);
    if (strlen(plaintext) + strlen(input) + 1 > MAX_PGRAPH_LENGTH)
        break;

    strcat(plaintext, input);
    strcat(plaintext, " ");
}

【讨论】:

  • 这是我失败的测试的输入:'键:112,输入:在默认的“C”语言环境中,小写字母可以是:a b c d e f g h I j k l m n o p q r s t u v w x y z。这是在屏幕上打印的内容:'键:112 输入:在默认的“C”语言环境中,小写字母可以是:a b c d e f g h i j k l m n o p q r s t u 输出:Qv bpm lmnictb "K" twkitm, i twemzkiam tmbbmz qa ivg wn: i j k l m n o p q r b c s ' y z v x我很困惑为什么这个'@'会出现在输出的末尾。单引号内的任何内容都是打印到屏幕上的内容。
猜你喜欢
  • 2016-08-30
  • 2020-11-08
  • 2014-03-07
  • 2013-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-13
相关资源
最近更新 更多