I am currently writing a program called Encoding and Decoding strings with the Enigma Class. This was a class assignment, but it already has been turned in, and I would like help (I am not looking for the work to be done for me) so I may learn from my errors and become a better programmer.

My issue:

I have it compiling but the program crashes after I ask the user to enter in a string to Encode.
I assume (after debugging) that it has to do with the way I am handling the string as well as what I do to the string after I have implemented it (tried to convert it).

Algorithm for Enigma Class:

The user enters a string (in main) and it is passed into the Enigma object to be encoded. The Enigma class uses a “key” to encode the message. The key is an integer value between (and including) 1-50. To encode the message string, each character of the message is converted to its associated ASCII numeric value and the key value is added to it. The new number is then converted back to a character. To decode the message, each letter is converted to an int, the key subtracted from it, and the new value converted to a char.

There other issue I may be encountering is my method of "Wrapping" the values for example:
I have to be sure that the coded message characters are all within 32-126. When the key is added to the character, if the value is larger than 126, I would like the values “wrap” around in the following manner. The value 127 => 32, 128 => 33, 129 => 34, etc. All this is already done, but just like my other issue, they are bother errors that I encounter in the Encode() and Decode() functions.


Thank you guys for all the help you have given me before.


I will post my really long code, the more the merrier.

Driver.cpp

// PROGRAM:		PROGRAM #7  |  ENIGMA ENCODING & DECODING PART I (w/ ENIGMA CLASS)
//  E-MAIL:		ppotter03@inbox.com
//    FILE:		Driver.cpp

#include <string>
#include <sstream>
#include <iostream>
#include <fstream>

#include "Enigma.h"
#include "Functions.h"

using namespace std;

int main()
{
	/******** VARIABLE DECLARATION ********/
	int Choice, KEY;
	bool bRead = false;
	string CodedMSG, OriginalMSG;
	/********    END DECLARATION   ********/
	
	ObjScreen();

	Enigma E;

	do 
	{
		cout << "\n -------------------------------------------------------- ";
		cout << "\n  ENIGMA ENCODING & DECODING MAIN MENU ";
		cout << "\n  (1)  <--- Encode A Message Using Your Key?	";			
		cout << "\n  (2)  <--- Encode A Message Using Generated Key? "; 	
		cout << "\n  (3)  <--- Decode A Message Read From A File? ";
		cout << "\n  (4)  <--- EXIT \n";
		cout << "\n Enter One Of The Menu Options:    ";
		cin  >> Choice;

		switch (Choice)
		{
			case 1 :
				cout << "\n Enter Key (1-50 Inclusive):  ";
				cin  >> KEY;

				cout << "\n Enter Message To Encode:  ";
				cin  >> OriginalMSG;

				E.setOriginalMSG(OriginalMSG, KEY);
				
				cout << "\n ORIGINAL MESSAGE: " << OriginalMSG;
				cout << "\n  ENCODED MESSAGE: " << E.getCodedMSG();
				cout << "\n		         KEY: " << E.getKEY() << "\n";

				WriteFile(CodedMSG, KEY);

				break;

			case 2 :
				cout << "\n Enigma Is Generating A Key... ";
				
				cout << "\n Enter Message To Encode:  ";
				cin  >> OriginalMSG;

				E.setOriginalMSG(OriginalMSG);
				
				cout << "\n ORIGINAL MESSAGE: " << OriginalMSG;
				cout << "\n  ENCODED MESSAGE: " << E.getCodedMSG();
				cout << "\n		         KEY: " << E.getKEY() << "\n";

				WriteFile(CodedMSG, KEY);

				break;

			case 3 :

				bRead = ReadFile(CodedMSG, KEY);
				
				if ( bRead == false )
				{
					cout << "\n ERROR! Unable To Locate File. \n";
				}
				
					E.setCodedMSG(CodedMSG, KEY);
					
					cout << "\n ENCODED MESSAGE: " << CodedMSG;
					cout << "\n DECODED MESSAGE: " << E.getDecodedMSG();
					cout << "\n		        KEY: " << E.getKEY() << "\n";

				break;

			case 4 :
				cout << "\n The Program Will Now EXIT. \n";
		}

	}while (Choice != 4); 
	
	cout << "\n EXITING C++ ENIGMA ENCODING & DECODING...... BYE! \n\n";
	
	return (0);
}
// END OF ENIGMA ENCODING & DECODING PART I

Enigma.h (Class)

// PROGRAM:		PROGRAM #7  |  ENIGMA ENCODING & DECODING PART I (w/ ENIGMA CLASS)
//  E-MAIL:		ppotter03@inbox.com
//    FILE:		Enigma.h

#ifndef _ENIGMA_H
#define _ENIGMA_H

#include <string>
#include <sstream>

using namespace std;

class Enigma
{
private:

	string OriginalMSG;
	string CodedMSG;
	int KEY;

	// Encode() ---> CodedMSG
	void Encode();
	// Decode() ---> OriginalMSG
	void Decode();

public:

	Enigma();

	// Uses rand() to assign KEY (use same seed)
	void setOriginalMSG(string OM);

	// Check for valid KEY (1-50), if value not between 1-50 assign key to 1 (key = 1)
	void setOriginalMSG(string OM, int K);

	void setCodedMSG(string CM, int K);

	int getKEY() { return KEY; }

	// Return CodedMSG <--- Encode()
	string getCodedMSG() { return CodedMSG; }

	// Return OriginalMSG <--- Decode()
	string getDecodedMSG() { return OriginalMSG; }

};

#endif

Enigma.cpp

// PROGRAM:		PROGRAM #7  |  ENIGMA ENCODING & DECODING PART I (w/ ENIGMA CLASS)
//  E-MAIL:		ppotter03@inbox.com
//    FILE:		Enigma.cpp

#include <string>
#include <sstream>
#include <cstdlib>
#include <ctime>
#include <cstring>

#include "Enigma.h"
#include "Functions.h"

using namespace std;

Enigma::Enigma()
{
	OriginalMSG = "The Enigma Class";
	KEY = 0;
	CodedMSG;
}

void Enigma::setOriginalMSG(string OM)
{
	srand((unsigned)time(0)); 
	int temp = (rand() % 50) + 1;

	KEY = temp;

	OriginalMSG = OM;

	Encode();
}

void Enigma::setOriginalMSG(string OM, int K)
{
	OriginalMSG = OM;
	KEY = K;

	if(KEY < 1 || KEY > 50)
	{
		KEY = 1;
	}

	Encode();
}

void Enigma::setCodedMSG(string CM, int K)
{
	CodedMSG = CM;
	KEY = K;

	Decode();
}

void Enigma::Encode()
{
	stringstream SS;
	char C;
	int i, N, Nshift;

	// REMOVING NULL CHAR
	for( i = 0; i < OriginalMSG.length()-1; ++i)
	{	
		C = OriginalMSG.at(i);
		N = (int)C;
		Nshift = N + KEY;
				
		if (Nshift >= 127)
		{
			Nshift = (Nshift - 126) + 31;
		}
		else if (Nshift <= 31)
		{
			Nshift = (32 - Nshift) - 126;
		}	
		
	    CodedMSG.at(i) = (char)Nshift;
	}
	
}

void Enigma::Decode()
{
	char C2;
	int i, N2, Nshift2;

	// REMOVING NULL CHAR
	for( i = 0; i < CodedMSG.length()-1; ++i)
	{
		C2 = CodedMSG.at(i);
		N2 = (int)C2;
		Nshift2 = N2 - KEY;
		
		/*if (Nshift2 >= 127)
		{
			Nshift2 = (Nshift2 - 126) + 31;
		}
		else if (Nshift2 <= 31)
		{
			Nshift2 = (32 - Nshift2) - 126;
		}	
		*/
		OriginalMSG.at(i) = (char)Nshift2;
	}
}

Functions.h & Functions.cpp

// PROGRAM:		PROGRAM #7  |  ENIGMA ENCODING & DECODING PART I (w/ ENIGMA CLASS)
//  E-MAIL:		ppotter03@inbox.com
//    FILE:		Functions.h

#include <string>
#include <sstream>
#include <fstream>

using namespace std;

void ObjScreen();
bool ReadFile(string &CodedMSG, int &KEY);
void WriteFile(string CodedMSG, int KEY);


// PROGRAM:		PROGRAM #7  |  ENIGMA ENCODING & DECODING PART I (w/ ENIGMA CLASS)
//  E-MAIL:		ppotter03@inbox.com
//    FILE:		Functions.cpp

#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>

#include "Functions.h"

using namespace std;

void ObjScreen()
{
	// AUTHOR, TITLE, ASSIGNMENT & INTRODUCTION
	 cout << "\n --------------------------------------------------------     ";
	 cout << "\n	C++ ENIGMA ENCODING & DECODING PART I					  ";
	 cout << "\n --------------------------------------------------------     ";
	 cout << setw(15) << "\n	    AUTHOR:	" << setw(15)<< " Page Lynn Potter";
	 cout << "\n --------------------------------------------------------     ";
	 cout << "\n \"Enigma\" is based on a inclusive key-shift ASCII algorithm.";
	 cout << "\n The user enters a message & key or key is randomly generated ";
	 cout << "\n (w in specification). The key is added to or subtracted from ";
	 cout << "\n the message to encode/decode.                              \n";
}

bool ReadFile(string &CodedMSG, int &KEY)
{
	string FileName;
	bool bRead = true;

	cout << "\n Enter Filename Containing Coded Message (\'FILENAME.txt\'): ";
	cin  >> FileName;
	
	fstream input;
	input.open(FileName.c_str(), fstream::binary);
	
	if( !input)
	{
		cout << "\n ERROR! Can't Find The File. \n";
		bRead = false;
	}
	while( !input.eof())
	{
		// FIRST LINE - ENCODED MESSAGE
		getline(input, CodedMSG);
		// SECOND LINE - INTEGER KEY VALUE
		input >> KEY;

		bRead = true;
	}

	input.close();

	return bRead;
}

void WriteFile(string CodedMSG, int KEY)
{
	string FileName;

	cout << "\n Enter Name To Save Output File As?  ";
	cout << "\n \'FILENAME.txt\'  --->  " << FileName;

	cout << "\n Writing Coded Message & Key To " << FileName << endl;

	ofstream output;
	output.open(FileName.c_str(), ifstream::binary);

	output << CodedMSG;
	output << KEY << endl;

	output.close();
}

I apologize for the length of the program, and my error is mainly in Encode() & Decode() in the Enigma Class.
I believe this is where my error is, anyway when I use a break point here the program ran through, if I don't then it crashes. If you guys could point me in the correct direction I would be greatly obliged. If there is something that I could do different, that would produce better results please feel free to tell me.

Thank you very much,


Potter

When you say it crashes, when does it crash? Do you know at
what line?

Also the cipher you are doing is called ceaser shift cipher.

If you would like to wrap a encoded char to be within 32-126,
then use the modulus operator, although your method looks
like it works but not completely sure.

And also there is no need to convert the char to int and the int back
to char just to add a key to int. You can add the key to char
just like you would to an int. The compiler will implicitly convert
the char to an int during operations that you are performing.

When you say it crashes, when does it crash? Do you know at
what line?

Also the cipher you are doing is called ceaser shift cipher.

If you would like to wrap a encoded char to be within 32-126,
then use the modulus operator, although your method looks
like it works but not completely sure.

And also there is no need to convert the char to int and the int back
to char just to add a key to int. You can add the key to char
just like you would to an int. The compiler will implicitly convert
the char to an int during operations that you are performing.

OK I checked it out, and it appears to be crashing or getting a run-time error (But it complies), so is it the logic then?
I notice that I get the message at line 80 (I believe).
So, I think the message isn't getting put into the assigned variable (CodedMSG).

Here is what I had tried, based on what you told me.
Although I never get as far as Decode(). I stop right at the last part of Encode()

void Enigma::Encode()
{
	char C;
	int i, Nshift;

	// REMOVING NULL CHAR
	for( i = 0; i < OriginalMSG.length()-1; ++i)
	{	
		C = OriginalMSG.at(i);
		Nshift = C + KEY;
		/*N = (int)C;
		Nshift = N + KEY;*/
				
		if (Nshift >= 127)
		{
			Nshift = (Nshift - 126) + 31;
		}
		else if (Nshift <= 31)
		{
			Nshift = (32 - Nshift) - 126;
		}	
		
	    CodedMSG.at(i) = Nshift;
	}
	
}

void Enigma::Decode()
{
	char C2;
	int i, Nshift2;

	// REMOVING NULL CHAR
	for( i = 0; i < CodedMSG.length()-1; ++i)
	{
		C2 = CodedMSG.at(i);
		Nshift2 = C2 - KEY;
		/*N2 = (int)C2;
		Nshift2 = N2 - KEY;*/
		
		/*if (Nshift2 >= 127)
		{
			Nshift2 = (Nshift2 - 126) + 31;
		}
		else if (Nshift2 <= 31)
		{
			Nshift2 = (32 - Nshift2) - 126;
		}	
		*/
		OriginalMSG.at(i) = Nshift2;
	}
}
This question has already been answered. Start a new discussion instead.