As the first step for writing a Morse code practice program, I thought I'd start with the very simplest step of a text-based Morse code translator. This simple program reads lines from stdin
and emits them as a text-based representation of the Morse code equivalent. Any character that doesn't have a Morse code equivalent is simply skipped.
I'm interested particularly in a few things.
- Is there a better representation than
map
that I should use? - Is there a way to declare it as
constexpr
? - Would this be better implemented as a
facet
?
The private emit
member function is intended to be replaced by a mechanism that will queue up audio output.
Morse.cpp:
#include <iostream>
#include <sstream>
#include <cctype>
#include <map>
/* Morse code ITU-4 M.1677 */
class Morse
{
public:
Morse &operator<<(char ch) { emit(ch); return *this; }
Morse &operator<<(const std::string &msg)
{
for (const auto &ch : msg)
emit(ch);
return *this;
}
private:
void emit(const char &ch) const {
std::cout << coding[std::toupper(ch)] << ' ';
}
static std::map<const char, const std::string> coding;
};
std::map<const char, const std::string> Morse::coding = {
{' ', " "},
{'\n', "\n"},
{'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', "--.."},
{'1', ".----"},
{'2', "..---"},
{'3', "...--"},
{'4', "....-"},
{'5', "....."},
{'6', "-...."},
{'7', "--..."},
{'8', "---.."},
{'9', "----."},
{'0', "-----"},
{'.', ".-.-.-"},
{',', "--..--"},
{'?', "..--.."},
{'-', "-...-"},
{'/', "-..-."},
{'@', ".--.-."},
{'+', ".-.-."},
{'=', "-..."},
{'\'', ".----"},
{'(', "-.--"},
{')', "-.--."},
{'\"', ".-..-"},
{'\x04', "...-.-"}, //EOT = SK
};
int main()
{
using namespace std;
Morse morse;
string line;
while (getline(cin, line))
morse << line << '\n';
}