使用C ++实现Caesar Cipher时出错

时间:2016-01-29 04:50:06

标签: c++

我正在尝试使用C ++实现Caesar Cipher。方向是使用已加密的文件:

5
Asi ymj rtrjwfymjx tzylwfgj.
Aqq rnrxd bjwj ymj gtwtlwtajx
Dni ldwj fsi ldrgqj ns ymj bfgj.
Tbfx gwnqqnl fsi ymj xnymjd ytajx

数字5表示应用于文本的班次。我必须解码Caesar加密文本并反转线条,如第1行第4行和第2行第3行。每行的第一个字母不需要解码(大写字母)。

运行程序后,文本应如下所示:

Twas brillig and the sithey toves
Did gyre and gymble in the wabe.
All mimsy were the borogroves
And the momerathes outgrabe.

截至目前,我有这段代码:

#include <iostream>
#include <vector>
#include <string>
#include <fstream>

using namespace std;

char decipher (char c, int shift);

int main(){
    //declare variables
    char c;
    string deciphered = "";
    int shift;
    vector <string> lines;

    //ask for filename and if not found, keep trying
    ifstream inFile;
    string filename;
    cout << "What is the name of the file? ";
    cin >> filename;
    inFile.open(filename);
    while (!inFile){
        cout << "File not found. Try again: ";
        cin >> filename;
        inFile.open(filename);
    }

    //find shift from file
    inFile >> shift;

    //get lines from file
    inFile >> noskipws;
    while (inFile >> c){
        char decipheredChar = decipher (c, shift);
        deciphered += decipheredChar;
    }
    cout << deciphered;

}

char decipher (char c, int shift){
    string letters = "abcdefghijklmnopqrstuvwxyz";
    if (c == 'T'){
        return c;
    }
    else if (c == 'D'){
        return c;
    }
    else if (c == 'A'){
        return c;
    }
    else if (c == ' '){
        return c;
    }
    else {
        int currentPosition = letters.find(c);
        int shiftedPosition = currentPosition - shift;
        if (shiftedPosition < 0){
            shiftedPosition = 26 + shiftedPosition;
        }
        char shifted = letters[shiftedPosition];
        return shifted;
    }
}

我得到的结果是:

uAnd the momerathes outgrabeuuAll mimsy were the borogrovesuDid gyre and gymble in the wabeuuTwas brillig and the sithey tovesu

如何摆脱你的角色并逐行分开?我有一个想法,使用向量反转线条并使用向后计数循环,但我不知道如何到达那里。请帮忙。谢谢。

1 个答案:

答案 0 :(得分:2)

要回答你的问题,'你是新行。你读他们并解密他们,所以他们改变,结果从字母中提取。您应该能够将另一个案例添加到decipher()以仅保留换行符:

char decipher (char c, int shift){
    string letters = "abcdefghijklmnopqrstuvwxyz";
    if(c == '\n'){  // do not modify new lines.
        return c;
    }
    else if (c == 'T'){
        return c;
    }
    // ...
}

可能最简洁的反转线的方法是在阅读角色时解析它们。您可以按相反顺序从矢量弹出它们。一个有效(但不健壮)的例子是将以下内容添加到while循环中:

while (inFile >> c){
    char decipheredChar = decipher (c, shift);
    deciphered += decipheredChar;
    if(decipheredChar=='\n'){        //if full line
        lines.push_back(deciphered); //push line
        deciphered = "";             //start fresh for next line
    }
}
lines.push_back(deciphered+'\n'); //push final line (if no newline)

while(!lines.empty()){
    cout << lines.back(); //prints last line
    lines.pop_back();     //removes last line
}

我说不健全,因为有些小事你可能仍需要注意。例如,这会从5之后读取存储换行符,如果文件以换行符结尾,我会在末尾添加一个空行...我会留下一些细节以便清理。