I have been implementing the Caesar cipher using object oriented programming. The problem is that when I call the encrypted function I get the same message as the user input... The message is not being encrypted properly.
For example if I write "abc" instead of getting "bcd", I am getting "abc". I tried it in C++, the code was working (the logic was fine) but I tried using object-oriented programing in C++ and created three files to separate the code.
Can anyone help or identify any mistake that I may have made?
Executable test File (main
function):
#include <iostream>
#include <string>
#include "CyclicShift.h"
using namespace std;
int main()
{
string text;//the string that holds the user input
int key;//key holds the number by which the user wants the alphabets to be shifted
cout << "Enter your phrase: " << endl;
getline(cin, text);//gets the user input ( including spaces and saves it to the variable text)
cout << "Please choose a number(key) for which you wants the alphabets to be shifted: " << endl;
/*Note: the key can either be positive (forward shifting), negative (backward shifting) or zero (no shifting)*/
cin >> key;//User input for number by which alphabets are going to be shifted
const CyclicShift aShift;
cout << "Encrypted Message : " << aShift.Encrypt(text, key) << endl;
//system("Pause");
return 0;
}
Header file .h
:
#pragma once
#include <iostream>
#include<string>
//Note: No using "namespace std;" in header files
class CyclicShift
{
private:
char fUpperCase[26];//A-Z
char fLowerCase[26];//a-z
public:
CyclicShift();
std::string& Encrypt(std::string& aOriginalMessage, int &aKey) const;// Function Prototype. This declares Encrypt to be a function that needs one string and one integer variables as arguments. Reference operator & in prototype
};
Source file .cpp
:
#include "CyclicShift.h"
#include<iostream>
#include<string>
using namespace std;
CyclicShift::CyclicShift()
{
char fUpperCase[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};//Initialization of class member
char fLowerCase[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};//Initialization of class member
}
string& CyclicShift::Encrypt(string& aOriginalMessage, int & aKey) const
{
int z;//z holds the value (int) of the length of the user input ( including spaces)
z = (int)aOriginalMessage.length(); /*give the variable z the value of the user input length and length is normally an unsigned long integer hence
we have to typecast it*/
/*counter that makes it keep looping until it "encrypts" all of the user input (that's why it keeps looping while its less than z)*/
for (int i = 0; i < z; i++)
{
for (int j = 0; j < 26; j++)
{
if (aOriginalMessage[i] == fLowerCase[j] || aOriginalMessage[i] == fUpperCase[j])
{
if (aKey > 0)
{
//another counter that loops forwards key times by incrementing method
for (int counter = 0; counter < aKey; counter++)
{
/*it checks if the letter text[x] is 'z' and if it is 'z' it will make it 'a'*/
if (aOriginalMessage[i] == 'z')
{
aOriginalMessage[i] = 'a';
}
else if (aOriginalMessage[i] == 'Z')
{
aOriginalMessage[i] = 'A';
}
else
{
aOriginalMessage[i]++;
}
}
}
else if (aKey < 0)
{
//another counter that loops backwards key times by decrementing method
for (int counter = 0; counter < abs(aKey); counter++)
{
/*it checks if the letter text[x] is 'a' and if it is 'a' it will make it 'z'*/
if (aOriginalMessage[i] == 'a')
{
aOriginalMessage[i] = 'z';
}
else if (aOriginalMessage[i] == 'A')
{
aOriginalMessage[i] = 'Z';
}
else
{
aOriginalMessage[i]--;
}
}
}
else
{
aOriginalMessage[i];//No alphabet shifts
}
}
else {
continue;
}
break;
}
}
return aOriginalMessage;
}
Above are the three code files of my object-oriented implementation: Testing (main), Header and source .cpp file.
You should declare fUpperCase
and fLowerCase
as static
and initialize them in the header file. In your code the variables you initialized are local to the constructor, while the private members stay untouched.
EDIT
If you have to initialize them in the constructor, well, you can do something like this:
class CyclicShift
{
private:
char fUpperCase[26]; // A-Z
char fLowerCase[26]; // a-z
// ... etc. ...
}
CyclicShift::CyclicShift()
{
for ( int i = 0; i < 26; ++i) {
fUpperCase[i] = 'A' + i;
fLowerCase[i] = 'a' + i;
}
}