我被分配编写一个密码,该密码接收带有字符的文件,并用数字(1-10)更改所有字符。困难的部分是加密所需要的。 "每次处理新行时,键值增加1。但是,键每五(旋转值)行重置一次并返回其原始值"
例如:如果用户为密钥输入3,则1,2,3,4和5行分别用3,4,5,6和7加密。然后用3加密第6行,依此类推。目前,我甚至无法让一个简单的班次正常工作。没有任何语法错误,它编译没有错误。但是,当我打开输出文件时,我的文本编辑器崩溃,因为我以某种方式创建了一个510mb文本文件.....我知道:/
所以我正在寻找你愿意给予的任何帮助。现在已经工作了几个多小时,并认为现在是时候寻求帮助了。如果您愿意花时间给出任何建议/解决方案,请提前感谢大家。 :)
/*
*File: Lab5
*Author: Nathaniel Goodhue
*Created on: 10/14/15
*Description: Encrypts an input message by
*shifting characters by a given number
*/
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <fstream>
using namespace std;
/*
*Displays a menu that allows the user to set a shift key value,
*encrypt or decrypt a message, or quit
*/
void displayMenu()
{
cout<<"1. Set the shift key value"<<endl;
cout<<"2. Encrypt"<<endl;
cout<<"3. Decrypt"<<endl;
cout<<"4. Quit"<<endl;
}
/*
*gets the value that characters will be shifted by
*/
int getKeyValue(int &keyValue)
{
keyValue = 0;
do
{
cout<<"Enter the shift key value between 1 and 10: ";
cin >>keyValue;
if(keyValue >10 ||keyValue <1)
cout<<"Key value must be between 1 and 10."<<endl;
}
while(keyValue >10 || keyValue <1);
return keyValue;
}
/*
*gets the input and output file names
*/
void getFileNames(ifstream &fin1, ofstream &fout1, ifstream &fin2, ofstream &fout2)
{
fin1.open("inputMsg.txt");
fout1.open("encryptedMsg.txt");
fin2.open("encriptedMsg.txt");
fout2.open("revertedMsg.txt");
}
/*
*shifts characters in input file by (int keyValue)
*/
void encrypt(int &keyValue, ifstream &fin1, ofstream &fout1)
{
char ch;
while(!fin1.eof())
{
fin1.get(ch);
while(ch != ' ')
{
fout1<<static_cast <char> (static_cast <int>(ch)+keyValue);
}
}
}
/*
*shifts characters back to original
*/
void decrypt(int &keyValue, ifstream &fin2, ofstream &fout2)
{
char ch;
while(!fin2.eof())
{
fin2.get(ch);
while(ch != ' ')
{
fout2<<static_cast <char> (static_cast <int>(ch)-keyValue);
}
}
}
int main()
{
int menuChoice, keyValue;
ifstream fin1;
ofstream fout1;
ifstream fin2;
ofstream fout2;
getFileNames(fin1, fout1, fin2, fout2);
do{
displayMenu();
cin >> menuChoice;
if (menuChoice == 1)
{
getKeyValue(keyValue);
}
else if (menuChoice == 2)
{
cout<<"Message successfully encrypted with "<<keyValue<<" as its key value"<<endl;
encrypt(keyValue, fin1, fout1);
}
else if (menuChoice == 3)
{
cout<<"Message successfully decrypted with "<<keyValue<<" as its key value"<<endl;
decrypt(keyValue, fin2, fout2);
}
else if(menuChoice > 4 || menuChoice < 1)
cout<<"Invalid menu choice. Must be between 1 and 4";
}
while(menuChoice != 4);
fin1.close();
fout1.close();
fin2.close();
fout2.close();
return 0;
}
另外我有4个文件的原因是因为需要decypher功能。
答案 0 :(得分:1)
您的问题出在加密功能中。特别是这一点:
fin1.get(ch);
while(ch != ' ')
{
fout1<<static_cast <char> (static_cast <int>(ch)+keyValue);
}
在第一次循环运行时,fin1.get(ch)
将ch
设置为输入文件的第一个字符。然后输入一个while
循环,将(加密的)第一个字符放入文件中,一遍又一遍,直到ch
为空格。但是你读取了在这个循环之外的下一个字符,所以永远不会达到结束循环的条件。
您需要一个简单的if
语句来避免对空格进行加密。除此之外,你的当前代码总是会拾取(和加密)EOF,因为EOF位不会被设置,直到你尝试读取文件的结尾(这是在循环中完成的,所以不会和#39; t在你加密并附加到文件之前检查。您可以使用ifstream good()
检查循环内是否存在任何问题(EOF或错误)和break
(如果有),以避免EOF造成额外问题最后的角色:
void encrypt(int &keyValue, ifstream &fin1, ofstream &fout1)
{
char ch;
while(fin1.get(ch))
{
if(!fin1.good()) break;
if (ch != ' ') fout1<<static_cast <char> (static_cast <int>(ch)+keyValue);
else fout1<<' ';
}
}
您也需要对解密进行类似的更改。另外,为了挑剔,我建议
cout<<"Message successfully encrypted with "<<keyValue<<" as its key value"<<endl;
并且成功加密/解密之后应该来到,而不是之前。
另一个问题是文件流在程序开始时全部打开并在结束时关闭的方式。如果您尝试在程序的同一运行中加密和解密消息,则会失败,因为fin2
在实际写入消息之前打开encryptedMsg.txt
。 <{1}}(将加密的消息写入该文件)需要先关闭。
我实际上只是建议您只在需要时打开流。不是在开头打开所有流并在结束时关闭所有流,而是在加密消息之前打开fout1
(输入消息)和fin1
(加密输出),然后立即关闭它们。同样,在解密之前立即打开fout1
(加密消息作为输入)和fin2
(解密版本),然后立即关闭它们。或者,更好的是,您可以重用流 - 只需要一个fout2
对象和一个ifstream
对象,每个对象在加密/解密之前和之后打开和关闭相应的文件。
答案 1 :(得分:0)
您的程序永远不会停止读取输入文件。如果您的输入文件不包含空格字符,那么此循环将永远运行,这就是导致输出非常大的原因。
while(ch != ' ')
将这两行更改为
while(fin1.good())
使其在文件结束处停止(EOF)。
答案 2 :(得分:0)
不要试图一次完成所有事情。从一个简单的程序开始读取文件并对其进行标准的凯撒转换。当且仅当您正确地工作时,每个行尾都使用步进键进入第二阶段。
这样做可以一次处理一些错误,而不是将它们全部集中在一起。您还可以更轻松地找出代码的哪一部分导致错误。