C++ Program: Translating Text to Morse Code Program needs to be able to translat
ID: 3669212 • Letter: C
Question
C++ Program: Translating Text to Morse Code
Program needs to be able to translate a character of input into the equivalent Morse code. The mappings of the characters to Morse code will be in an input file that your program will read in.
First of all, need at least 4 functions (including main function). General areas of delegation: file input, character translation, and primary processing loop (read in data from cin and translate it to Morse code)
Text to be translated will be read in from cin. Program will read in text from cin and translate it to Morse code as long as the user hasn't entered in the text quit as the input. Characters read in from cin should be folded into upper case (input of a and A should both map to Morse code .- character sequence). Space character should map to a space character. A character that doesn't map to Morse code (like $) should be ouput in double quotes (like "$") to indicate that text wasn't translated.
Processing:
Program will first ask for name of file that contains the mapping. Program should the open this file and read values into two arrays. One array will contain the characters that are being mapped from and second array will contain equivalent Morse code. Once array have been built, the program will read in text from cin and translate it into Morse code. An input text that contains lower case characters: quit will indicate that programming should stop.
Input File Format & Requirements:
Input file will contain mappings from characters to the equivalent Morse code. Program should be able to handle any mapping files that is given to it. Standarad verison of Morse code is defined by the mapping.txt file. This maps 39 characters to Morse code. There's a second file, mapping2.txt, that maps some additional characters and implements an extended version of Morse code. Program must be able to handle either of these files or any other files that follow the same format as mapping.txt and mapping2.txt files.
Character Mappings:
Program must dynamically read in the input file and create two arrays. Size of these arrays is the first value in the input file. Program must dynamically create two arrays based on size read in from the input file. Program must also free up memory used by two arrays before it ends. Program must work with any number of mappings and shouldn't be limited to values specified in two sample files.
Translation of Characters:
Most of the mappings of input characters to output characters is determined by the contents of the two arrays you create from input file. When you translate a space character, you must map that to a space character. Any character not in the input file will map to itself, but will be enclosed in double quotation marks in the output.
You want to read in an entire line of text from cin for your translations. You should use getline to do this.
Stopping the Program:
Program will terminate if input file can't be opened. You need to output an error message in this case. Your program will read in multiple lines of text from cin. value of quit will terminate the program.
Additional Requirements:
You must pass values from one function to another. No global variable are allowed in this program.
Program Output:
Here is some sample output. Your output of the text file must match what is shown here fro the same input.
Enter in the name of the input file that contains the mapppings (strings to Morse code)
mapping.txt [Enter]
Enter the string to be translated (or quit to exit)
Starting out w/C++: [Enter]
Translate to
... . .-.. .-.. --- .-- --- .-. .-.. -.. "!"
Enter the string to be translated (or quit to exit)
quit [Enter]
Explanation / Answer
main.cpp
#include <iostream>
#include "MEMsg.h"
int main()
{
string userInput; //stores one line of user input
//Initialize our maps/translations
MEMsg::initTranslation();
//Reads for input from user until eof is detected
while(getline(cin, userInput))
{
//Figure out whether input is morse or english:
if(MEMsg::isEnglish(userInput))
{
cout << MEMsg::toMorse(userInput) << endl;
}
else
{
cout << MEMsg::toEnglish(userInput) << endl;
}
}
return 0;
}
MEMsg.cpp
#include "MEMsg.h"
#include <sstream> //Allows us to add multiple strings into one string
#include <cctype> //For uppercase transformation
map<char, string> MEMsg::englishTranslation;
map<string, char> MEMsg::morseTranslation;
void MEMsg::initTranslation()
{
//Add the translation information:
englishTranslation['A'] = ".-";
englishTranslation['B'] = "-...";
englishTranslation['C'] = "-.-.";
englishTranslation['D'] = "-..";
englishTranslation['E'] = ".";
englishTranslation['F'] = "..-.";
englishTranslation['G'] = "--.";
englishTranslation['H'] = "....";
englishTranslation['I'] = "..";
englishTranslation['J'] = ".---";
englishTranslation['K'] = "-.-";
englishTranslation['L'] = ".-..";
englishTranslation['M'] = "--";
englishTranslation['N'] = "-.";
englishTranslation['O'] = "---";
englishTranslation['P'] = ".--.";
englishTranslation['Q'] = "--.-";
englishTranslation['R'] = ".-.";
englishTranslation['S'] = "...";
englishTranslation['T'] = "-";
englishTranslation['U'] = "..-";
englishTranslation['V'] = "...-";
englishTranslation['W'] = ".--";
englishTranslation['X'] = "-..-";
englishTranslation['Y'] = "-.--";
englishTranslation['Z'] = "--..";
englishTranslation['0'] = "-----";
englishTranslation['1'] = ".----";
englishTranslation['2'] = "..---";
englishTranslation['3'] = "...--";
englishTranslation['4'] = "....-";
englishTranslation['5'] = ".....";
englishTranslation['6'] = "-....";
englishTranslation['7'] = "--...";
englishTranslation['8'] = "---..";
englishTranslation['9'] = "----.";
englishTranslation['.'] = ".-.-.-";
englishTranslation[','] = "--..--";
englishTranslation['?'] = "..--..";
englishTranslation['''] = ".----.";
englishTranslation['!'] = "-.-.--";
englishTranslation['/'] = "-..-.";
englishTranslation['('] = "-.--.";
englishTranslation[')'] = "-.--.-";
englishTranslation['&'] = ".-...";
englishTranslation[':'] = "---...";
englishTranslation[';'] = "-.-.-.";
englishTranslation['='] = "-...-";
englishTranslation['+'] = ".-.-.";
englishTranslation['-'] = "-....-";
englishTranslation['_'] = "..--.-";
englishTranslation['"'] = ".-..-.";
englishTranslation['$'] = "...-..-";
englishTranslation['@'] = ".--.-.";
morseTranslation[".-"] = 'A';
morseTranslation["-..."] = 'B';
morseTranslation["-.-."] = 'C';
morseTranslation["-.."] = 'D';
morseTranslation["."] = 'E';
morseTranslation["..-."] = 'F';
morseTranslation["--."] = 'G';
morseTranslation["...."] = 'H';
morseTranslation[".."] = 'I';
morseTranslation[".---"] = 'J';
morseTranslation["-.-"] = 'K';
morseTranslation[".-.."] = 'L';
morseTranslation["--"] = 'M';
morseTranslation["-."] = 'N';
morseTranslation["---"] = 'O';
morseTranslation[".--."] = 'P';
morseTranslation["--.-"] = 'Q';
morseTranslation[".-."] = 'R';
morseTranslation["..."] = 'S';
morseTranslation["-"] = 'T';
morseTranslation["..-"] = 'U';
morseTranslation["...-"] = 'V';
morseTranslation[".--"] = 'W';
morseTranslation["-..-"] = 'X';
morseTranslation["-.--"] = 'Y';
morseTranslation["--.."] = 'Z';
morseTranslation["-----"] = '0';
morseTranslation[".----"] = '1';
morseTranslation["..---"] = '2';
morseTranslation["...--"] = '3';
morseTranslation["....-"] = '4';
morseTranslation["....."] = '5';
morseTranslation["-...."] = '6';
morseTranslation["--..."] = '7';
morseTranslation["---.."] = '8';
morseTranslation["----."] = '9';
morseTranslation[".-.-.-"] = '.';
morseTranslation["--..--"] = ',';
morseTranslation["..--.."] = '?';
morseTranslation[".----."] = ''';
morseTranslation["-.-.--"] = '!';
morseTranslation["-..-."] = '/';
morseTranslation["-.--."] = '(';
morseTranslation["-.--.-"] = ')';
morseTranslation[".-..."] = '&';
morseTranslation["---..."] = ':';
morseTranslation["-.-.-."] = ';';
morseTranslation["-...-"] = '=';
morseTranslation[".-.-."] = '+';
morseTranslation["-....-"] = '-';
morseTranslation["..--.-"] = '_';
morseTranslation[".-..-."] = '"';
morseTranslation["...-..-"] = '$';
morseTranslation[".--.-."] = '@';
}
bool MEMsg::isEnglish( const string& userInput )
{
//temp to hold single char from string for analysis
char tempChar = ' ';
//Loop through each char of userInput and analys for english
for(unsigned int index = 0; index < userInput.length(); index++)
{
tempChar = userInput.at(index);
//If char is anything but dot, dash, space, or #, it's considered english
if(tempChar == '.' || tempChar == '-' || tempChar == ' ' || tempChar == '#')
{
//Continue
}
else
{
//char was not morse, return true (english)
return true;
}
}
//no english found, return false (morse)
return false;
}
string MEMsg::toMorse( const string& English)
{
string returnValue;
//Just in case we get an empty string
if(English.size() < 1)
{
return " ";
}
else
{
stringstream addStrings; //store each character translation
map<char, string>::iterator it; //used to access map based on key
//Go through each english character and translate
for(unsigned int counter = 0; counter < English.size(); counter++)
{
//First we make sure the characters we are translating are uppercase
char upperChar = toupper(English.at(counter));
//Add the translation to the stringstream
if(toupper(English.at(counter)) != ' ')
{
//If char is not space, try to find it in englishTranslation
it = englishTranslation.find(upperChar);
//Look to see if we found a matching translation
if(it != englishTranslation.end())
{
//A match is found, so we add it to addStrings
addStrings << it->second;
}
else
{
//If no translation found, add error ........
addStrings << "........";
}
}
//Look at the next character to see if it is space
if(counter+1 < English.size())
{
if(toupper(English.at(counter+1)) == ' ')
{
//If the next character is space, add #
addStrings << '#';
}
else if(!(upperChar == ' '))
{
//Add a space to separate characters (between two morse strings)
addStrings << ' ';
}
}
}
//Convert the stringstream (all of the strings) into one string
returnValue = addStrings.str();
}
//Return our completed translation (or space if nothing in Morse)
return returnValue;
}
string MEMsg::toEnglish( const string& Morse)
{
stringstream englishChars;
stringstream oneString;
string tempString;
map<string, char>::iterator it;
for(unsigned int counter = 0; counter < Morse.size(); counter++)
{
if(Morse.at(counter) == '.' || Morse.at(counter) == '-')
{
oneString << Morse.at(counter);
}
else if(Morse.at(counter) == '#')
{
englishChars << ' ';
}
if((counter+1 < Morse.size()) && oneString.str() != "")
{
if(Morse.at(counter+1) == '#' || Morse.at(counter+1) == ' ')
{
//Examine previous findings
it = morseTranslation.find(oneString.str());
if(it != morseTranslation.end())
{
englishChars << it->second;
}
else
{
englishChars << "<error>" << oneString.str() << "</error>";
}
oneString.str("");
}
}
else if(oneString.str() != "")
{
//Examine previous findings
it = morseTranslation.find(oneString.str());
if(it != morseTranslation.end())
{
englishChars << it->second;
}
else
{
englishChars << "<error>" << oneString.str() << "</error>";
}
oneString.str("");
}
}
tempString = englishChars.str();
return tempString;
}
MEMsg::MEMsg()
{
}
MEMsg::~MEMsg()
{
}
MEMsg.h
#ifndef MEMSG_H
#define MEMSG_H
#include <string>
#include <map>
using namespace std;
/*
* class MEMsg
*
* Reasoning for static methods and members:
* Considering we don't need objects/instances of this class and
* we only use it as a container of sorts, we use static methods
* members. It is particularly important for the translation
* container "morseTranslation" to be static since multiple copies
* would take too much space for no reason. Specifically regarding
* the methods, they are static so we don't need to create an
* instance of our class in order to use them or the translation
*
* Reasoning for using map stl container:
* A map container is used since it allows us to easily store
* our translation in pairs. For example A is paired with .- so
* whether we need to convert A to .- or .- to A, we can quickly
* look at our map container and find out our translation either way
*/
class MEMsg
{
public:
//Holds Morse to English translation information.
static map<char, string> englishTranslation;
//Holds English to Morse translation information
static map<string, char> morseTranslation;
//Initializes morseTranslation and englishTranslation
static void initTranslation();
/* Analys string to see if it is English
* Parameters:
* const string& userInput - the string to analys
* Return:
* true if English, false if Morse
*/
static bool isEnglish( const string& userInput );
/* Translate English to Morse
* Parameters:
* const string& english - the English string to translate
* Return:
* the converted english in Morse as type string
*/
static string toMorse( const string& english );
/* Translate Morse to English
* Parameters:
* const string& morse - the Morse string to translate
* Return:
* the converted morse in English as type string
*/
static string toEnglish( const string& morse );
//Contructor and Deconstructor:
MEMsg();
~MEMsg();
};
#endif
testdata.txt
Here are eight dots for you >
- .... .- -. -.- ...
You're welcome!
-- --- .-. . ..--..
>
-.-- .- -.--
sample output
sh-4.3$ g++ -std=c++11 -o main *.cpp
sh-4.3$ main
testdata.txt
- . ... - -.. .- - .- .-.-.- - -..- -
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.