Reputation: 29
I am trying to write a caesar cipher program in c++. I use four functions, one for choosing shift key , two for encryption and decryption and the last is for implement the caesar cipher, using an inputfile for reading the text and an ouput the encrypted or the decrypted text into the output file. I am trying to run the code and it is being crashed. I think the problem is somewhere inside Caesar function. But i don't know what exactly is. Any ideas? This is my code:
#include <iostream>
#include <fstream>
using namespace std;
int chooseKey()
{
int key_number;
cout << "Give a number from 1-26: ";
cin >> key_number;
while(key_number<1 || key_number>26)
{
cout << "Your number have to be from 1-26.Retry: ";
cin >> key_number;
}
return key_number;
}
void encryption(char *w, char *e, int key){
char *ptemp = w;
while(*ptemp){
if(isalpha(*ptemp)){
if(*ptemp>='a'&&*ptemp<='z')
{
*ptemp-='a';
*ptemp+=key;
*ptemp%=26;
*ptemp+='A';
}
}
ptemp++;
}
w=e;
}
void decryption (char *e, char *w, int key){
char *ptemp = e;
while(*ptemp){
if(isalpha(*ptemp))
{
if(*ptemp>='A'&&*ptemp<='Z')
{
*ptemp-='A';
*ptemp+=26-key;
*ptemp%=26;
*ptemp+='a';
}
}
ptemp++;
}
e=w;
}
void Caesar (char *inputFile, char *outputFile, int key, int mode)
{
ifstream input;
ofstream output;
char buf, buf1;
input.open(inputFile);
output.open(outputFile);
buf=input.get();
while(!input.eof())
{
if(mode == 1){
encryption(&buf, &buf1, key);
}else{
decryption(&buf1, &buf, key);
}
output << buf;
buf=input.get();
}
input.close();
output.close();
}
int main(){
int key, mode;
key = chooseKey();
cout << "1 or 0: ";
cin >> mode;
Caesar("test.txt","coded.txt",key,mode);
system("pause");
}
Here are some details for my program.The template of my code is on top of my post.
The parameter w is the text in the beginning and the par e is the decrypted text. The encryption is being made, if we add the shift key in the w* text and we get the *e. The reverse procedure makes the decryption function, i have the encrypted text(*e) and i want to take the the decrypted text(*w), subtracking the key shift which i take from chooseKey function. In the Caesar function, i use an input file which contain some data and i want to extract in the output file the encrypted or the decrypted text instead. I have already implement encryption and decryption functions and my problem is how to use them in the Caesar function.I don't take any desirable result, my program is being crashed. Please mention my mistakes.Any solution?
Upvotes: 2
Views: 17147
Reputation: 394054
You pass the address of a single character into decryption
buf=input.get();
// ...
encryption(&buf, &buf1, key);
You then treat it as if it points to a null-terminated string.
while(*ptemp){
// ...
ptemp++;
}
That's not going to work well, because ptemp
doesn't point to a null-terminated string in the first place. The moment you do ptemp++
you're in Undefined Behaviour land.
Apart from this there are a host of other pitfalls (don't loop on .eof()
, e.g.) and potential improvements.
Edit Oh, and the assignments
w = e;
and
e = w;
have no effect whatsoever (you're assigning pointer values to local function arguments; upon returning, these variables don't even exist anymore).
Here's a cleaned up take, that I'd expect does what you want: Live on coliru
#include <iostream>
#include <fstream>
using namespace std;
int chooseKey() {
cout << "Give a number from 1-26: ";
int key_number;
while((!(cin >> key_number)) || (key_number < 1 || key_number > 26)) {
cout << "Your number have to be from 1-26 (" << key_number << "). Retry: ";
cin.clear();
}
return key_number-1;
}
template <typename InIt, typename OutIt>
void encryption(InIt f, InIt l, OutIt out, int key) {
for (InIt ptemp = f; ptemp != l; ++ptemp)
{
if(isalpha(*ptemp))
{
char base = islower(*ptemp)? 'a' : 'A';
*out++ = base + (*ptemp - base + key) % 26;
} else
*out++ = *ptemp;
}
}
void Caesar(const char *inputFile, const char *outputFile, int key, int mode) {
ifstream input(inputFile);
ofstream output(outputFile);
istreambuf_iterator<char> init(input), end;
ostreambuf_iterator<char> outit(output);
encryption(init, end, outit, mode? key : 26-key);
}
int main() {
int key, mode;
key = chooseKey();
cout << "1 or 0: ";
cin >> mode;
Caesar("test.cpp", "coded.txt", key, mode);
}
Upvotes: 4