/*
* Shane Grimminck
* Project 1
* Version 3.0 : Changed Compiler Warnings to level 4 and fixed possible loss of precision warnings
* 05/10/2011
*/
#include <iostream>
#include <fstream>
#include <string>
#include <locale>
#include <map>
#include <vector>
#include <crtdbg.h>
using namespace std;
//static const locale created for the purpose of providing the encode method and the block of code used to check for one letter words to check to see if the word is an alphabetic character
static const locale here ("");
//Function Encode
//Purpose is to encode the character passed in, using the cipher key and the jump table
//accepts a character, the cipher key and the 52 element jump table
char encode (char& ch, int const& cipherKey, vector<char>& jumptable)
{
//if its a character rotate it
if (isalpha(ch, here))
{
if ( ch >= 'a')
return jumptable[ch - 71];
else
return jumptable [ch-65];
}
//if its not a character put it back in.
else
{
return ch;
}
}
int main(int argc, char *argv[])
{
//debug memory leak checks
#if defined(_DEBUG)
int dbgFlags = ::_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
dbgFlags |= _CRTDBG_CHECK_ALWAYS_DF; //check block integrity on every memory call
dbgFlags |= _CRTDBG_DELAY_FREE_MEM_DF; // dont remove blocks on delete
dbgFlags |= _CRTDBG_LEAK_CHECK_DF; //check for memory leaks at process termination
_CrtSetDbgFlag( dbgFlags );
#endif
//create a vector to hold the 52 alphabetic characters and populate it
vector<char> jumptable;
for (int i = 'A'; i <= 'Z'; ++i)
{
jumptable.push_back(static_cast<char>(i));
}
for (int i = 'a'; i <= 'z'; ++i)
{
jumptable.push_back(static_cast<char>(i));
}
// parse the command line arguments and store them in a vector for use later
vector<string> args;
for( int i = 0; i < argc; ++i )
{
args.push_back( argv[i] );
}
//check to make sure we have recieved the correct number of arguments. If not exit the program
if (argc != 4)
{
cout << "Invalid Number of parameters. " << endl << "Input paramaters are [input file name] [cipher letter] [output file name]" << endl;
return EXIT_FAILURE;
}
//try to open the input file. If it cant be opened, exit the program
ifstream inputFile (args[1]);
if (!inputFile)
{
cout << "File " << args[1] << " could not be opened for reading" << endl;
return EXIT_FAILURE;
}
string currentWord; //current word we are working on
map<string, int> singleLetter; //map to hold the one letter words we find
while( inputFile >> currentWord)
{
if(currentWord.length() == 1 && isalpha(currentWord[0], here )) //if the word length is 1 and it is a alphabetic character put it into the map
{
++singleLetter[currentWord];
}
}
//figure out what number occurs is the highest in the map, its corresponding string element is the most common one letter word.
//Put that word into currentWord to save on memory, by not using another string
int freqOcc = 0;
for (map<string, int>::iterator it=singleLetter.begin(); it!=singleLetter.end(); ++it)
{
if (it->second > freqOcc)
{
currentWord = it->first;
freqOcc = it->second;
}
}
//output the results
cout << "Most frequent letter : " << currentWord << " occurs " << freqOcc << " times." << endl;
//find the cipher key and output the results
int n1 = 0, n2 = 0;
for (unsigned i = 0; i < jumptable.size(); ++ i)
{
if (currentWord[0] == jumptable[i])
n1 = i;
if (args[2][0] == jumptable[i])
n2 = i;
}
int const& cipherKey = n2 - n1;
cout << "Cipher Key is : " << cipherKey << endl;
vector<char> rotatedTable;
for (int i = 'A'; i <= 'Z'; ++i)
{
if(cipherKey >= 0)
rotatedTable.push_back(jumptable[((((i - 65) + cipherKey) % 52) )]);
else
rotatedTable.push_back(jumptable[((((i - 65) +( cipherKey+ 52)) % 52))]);
}
for (int i = 'a'; i <= 'z'; ++i)
{
if(cipherKey >= 0)
rotatedTable.push_back(jumptable[((((i - 71) + cipherKey) % 52) )]);
else
rotatedTable.push_back(jumptable[((((i - 71) +( cipherKey+ 52)) % 52))]);
}
//open the output file, exit if it cant be opened
ofstream outputFile (args[3]);
if (!outputFile.is_open())
{
cout << "Unable to open or create " << args[3] << endl;
return EXIT_FAILURE;
}
//clear the EOF from inputFile and set the seek position to 0 (start of the file)
inputFile.clear();
inputFile.seekg(0);
//read in a character at a time and output the character after encoding. Calls the encode function.
char originalValue;
while(inputFile.get(originalValue))
{
outputFile.put(encode(originalValue, cipherKey, rotatedTable));
}
//before end of the file, close files
if (inputFile.is_open())
inputFile.close();
if (outputFile.is_open())
outputFile.close();
}
|