我已经构建了一个程序来解密移位密码(Cesar Cipher)。它似乎采取输入并生成一个输出文件,但它是空的。我认为解密功能可能有问题,并尝试改变多项内容无济于事。我使用Bloodshed C ++编译和操作系统的Windows。
由于
kd7vdb
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
const int ARRAYSIZE = 128;
void characterCount(char ch, int list[]);
void calcShift( int& shift, int list[]);
void writeOutput(ifstream &in, ofstream &out, int shift);
int main()
{
int asciiCode = 0,
shift = 0;
string filename;
char ch;
ifstream infile;
ofstream outfile;
//input file
cout << "Input file name: ";
getline(cin, filename);
infile.open(filename.c_str());
if (!infile.is_open()) {
cout << "Unable to open file or it doesn't exist." << endl;
return 1;
}
//output file
cout << "Output file name: ";
getline(cin, filename);
outfile.open(filename.c_str());
int list[ARRAYSIZE] = {0};
while (infile.peek() != EOF)
{
infile.get(ch);
characterCount(ch, list);
}
infile.clear();
infile.seekg(0);
calcShift (shift, list); //Calculate the shift based on the <strong class="highlight">most</strong> characters counted
writeOutput(infile, outfile, shift); //Decypher and write to the other document
return 0;
}
void characterCount(char ch, int list[])
{
if (ch >= 'A' && ch <= 'z') //If the character is in the alphabet...
{
int asciiCode = 0;
asciiCode = static_cast<int>(ch); //Change it to the ASCII number
list[asciiCode]++; //And note it on the array
}
}
void calcShift( int& shift, int list[])
{
int maxIndex = 0, //Asuming that list[0] is the largest
largest = 0;
for (int i = 1; i < ARRAYSIZE; i++)
{
if (list[maxIndex] < list[i])
maxIndex = i; //If this is true, change the largest index
}
largest = list[maxIndex]; //When the maxIndex is found, then that has the largest number.
if (largest >= 65 && largest <= 90) //Calculate shift with <strong class="highlight">E</strong> (for upper-case letters)
shift = largest - 69;
if (largest >= 97 && largest <= 122) //For lower-case letters (<strong class="highlight">e</strong>)
shift = largest - 101;
}
void writeOutput(ifstream &infile, ofstream &outfile, int shift)
{
char ch;
int asciiCode = 0;
while (infile.peek() != EOF) { //Until it is the end of the file...
infile.get(ch); //Get the next character
if (ch >= 'A' && ch <= 'z') //If the character is in the alphabet...
{
asciiCode = static_cast<int>(ch); //Change it to the ASCII number
asciiCode += shift; //Do the shift
ch = static_cast<char>(asciiCode); //Change it to the shifted letter
}
outfile << ch; //Print to the outfile
}
}
答案 0 :(得分:0)
在我看来,您忘记了ofstream::close
输出文件。
答案 1 :(得分:0)
我注意到了一些严重的问题。
1)你在换班时不会四处走动。因此,如果shift = 20并且你得到了字符&#39; y&#39;,当你这样做时:
asciiCode = static_cast<int>(ch); //Change it to the ASCII number
asciiCode += shift; //Do the shift
ch = static_cast<char>(asciiCode);
asciiCode成为&#39; y&#39; + 20 == 141,这是标准128位ascii的结尾。我需要取数字mod,我猜,128。所以:
asciiCode = static_cast<int>(ch); //Change it to the ASCII number
asciiCode += shift; //Do the shift
asciiCode %= 128; // Wrap around
ch = static_cast<char>(asciiCode);
2)但是这仍然没有解决为什么你只是移动字母字符,而是将这些字母转移到结果中的非字母字符。
你为什么要用大小为128而不是52的数组来计算它们?或者只是26?
更重要的是,为什么要在代码中生成移位值?您需要知道该值才能稍后解码...
简而言之,我建议你这样做:
这就是Ceasar Cypher一般的工作方式。
3)关于打印问题,您是否尝试过调试?
我不能谈论Bloodshed C ++,但即使只是添加一个cout语句也会非常有用。例如:
std::cout << ch; //Print to cout for debugging
outfile << ch; //Print to the outfile
会告诉您错误是否在outfile处理中。
答案 2 :(得分:0)
您有几个逻辑错误。我认为你的最后两个功能应该更像:
void calcShift( int& shift, int list[])
{
int maxIndex = 0; //Asuming that list[0] is the largest
for (int i = 1; i < ARRAYSIZE; i++)
{
if (list[maxIndex] < list[i])
maxIndex = i; //If this is true, change the largest index
}
if (maxIndex >= 'A' && maxIndex <= 'Z') //Calculate shift with <strong class="highlight">E</strong> (for upper-case letters)
shift = 'E' - maxIndex;
if (maxIndex >= 'a' && maxIndex <= 'z') //For lower-case letters (<strong class="highlight">e</strong>)
shift = 'e' - maxIndex;
}
void writeOutput(ifstream &infile, ofstream &outfile, int shift)
{
char ch;
while (infile.peek() != EOF) { //Until it is the end of the file...
infile.get(ch); //Get the next character
if (ch >= 'A' && ch <= 'Z') //If the character is in the alphabet...
{
ch = 'A' + (((ch - 'A') + shift + 26) % 26);
}
if (ch >= 'a' && ch <= 'z') //If the character is in the alphabet...
{
ch = 'a' + (((ch - 'a') + shift + 26) % 26);
}
outfile << ch; //Print to the outfile
}
}
总结一下,largest
中不需要calcShift
,您需要从maxIndex
或'E'
中减去'e'
来计算转移,并且你在writeOutput
中对替换字符的计算相当远。
我不确定你为什么会得到一个空的输出文件,但这适用于我使用MSVC。