简体   繁体   English

凯撒密码程序来加密/解密段落

[英]Caesar Cipher Program to Encrypt/Decrypt a paragraph

First off, I am a newcomer to programming, so be gentle. 首先,我是编程新手,所以要保持柔和。 Also I have been working on this assignment to no avail. 另外,我一直在从事这项工作,但没有成功。 The assignment is to create a Caesar Cipher program which encrypts or decrypts a paragraph up to 100 characters. 任务是创建一个Caesar Cipher程序,该程序可以加密或解密最多100个字符的段落。 It's actually two separate labs. 实际上是两个单独的实验室。 The first lab is to encrypt, then the second lab is to decrypt. 第一个实验是加密,然后第二个实验是解密。 Once I figure out how to create the encryption program, the decryption program should be simple as I can just make semantic changes to decrypt instead of encrypt. 一旦弄清如何创建加密程序,解密程序就应该很简单,因为我可以进行语义更改以解密而不是加密。 Anyway here is the code I have so far. 无论如何,这里是我到目前为止的代码。 It passed 4 of the 5 tests they give us, but for some reason there is one test where the final character is an '@' symbol. 它通过了我们给我们的5个测试中的4个,但是由于某种原因,有一个测试的最终字符是一个'@'符号。 This makes no sense to me as it does not happen in any other tests, and I believe that my code places a '\\0' symbol at the of the string, so '@' should not be showing up in this one test. 这对我来说没有意义,因为它不会在其他任何测试中发生,并且我认为我的代码在字符串的处放置了“ \\ 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);
// ---------------------- --------------------------------------------------    ---------
}

As you can see, the lab gave us the setup and multiple blocks of code, and I am responsible for the actual Caesar cipher portion of the coding. 如您所见,实验室为我们提供了设置和多个代码块,我负责编码的实际Caesar密码部分。 My question is, am I not properly setting the '\\0' at the last position in C? 我的问题是,我在C的最后位置是否未正确设置'\\ 0'? One thing I noticed as well is that if I type an input such as "The dog ran", when input is printed to the screen, it will print "The dog ran ran ran ran ran.." until it hits 100 characters. 我还注意到的一件事是,如果我输入“狗跑了”之类的输入,当输入被打印到屏幕上时,它将打印“狗跑了ran跑了..”,直到达到100个字符。 Luckily, all of the tests they give us to run are paragraphs which exceed 100 characters, so I actually don't have to worry about passing a test in which I'm encrypting less than 100 characters. 幸运的是,它们提供给我们的所有测试都是超过100个字符的段落,因此我实际上不必担心通过一个加密少于100个字符的测试。 But I would still like to know why my plaintext string is repeating the last input word over and over. 但是我仍然想知道为什么我的明文字符串会不断重复最后一个输入的单词。 Sorry for the ridiculously long post, I have tried everything though and do not know where I am going wrong. 抱歉,发布了这么长的帖子,我已尽力尝试了一切,却不知道我要去哪里出错。

It repeats the last word because the you do not exit the infinite loop. 它重复最后一个单词,因为您不会退出无限循环。

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

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

The only way you exit the loop is executing the break statement and this is only possible with total lenghts of input and plaintext being greater than MAX_PGRAPH_LENGTH . 退出循环的唯一方法是执行break语句,并且只有在inputplaintext总长度大于MAX_PGRAPH_LENGTH ,这才是可能的。 The reason why only the last word is being repeated is because most probably scanf() reads the input word by word. 之所以只重复最后一个单词,是因为scanf()很可能逐字读取输入的单词。

Also, the reason why you did not pass the test case with @ character might be due to the fact that alphabetic characters start with decimal 65 (corresponds to A), and the decimal value of @ is 64. The difference between A and @ being 1 and the code failing the test case with @ is not a coincidence in my opinion. 另外,未通过@字符通过测试用例的原因可能是由于字母字符以十进制65开头(对应于A),而@的十进制值为64。A和@之间的区别是1和用@导致测试用例失败的代码在我看来不是巧合。 So, I think you should double-check the arithmetic operations and trace the code for a sample input. 因此,我认为您应该仔细检查算术运算并跟踪示例输入的代码。

The repetition is in the supplied code... not in your code. 重复出现在提供的代码中……不在您的代码中。

Read next word (forever), until the max paragraph length is reached. 永远阅读下一个单词,直到达到最大段落长度。 If there is no next word, the value of input is not updated, and is simply repeated until you reach a total length of MAX_PGRAPH_LENGTH 如果没有下一个单词,则输入的值不会更新,只会重复输入,直到总长度达到MAX_PGRAPH_LENGTH

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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