Code:
#include <iostream>
#include <string>
struct morse_node
{
const char ch;
const morse_node *dot;
const morse_node *dash;
};
/*
E T
I A N M
S U R W D K G O
H V F L P J B X C Y Z Q
5 4 3 2 1 6 7 8 9 0
*/
const morse_node
mc_0 = { '0', NULL, NULL },
mc_9 = { '9', NULL, NULL },
mc_8 = { '8', NULL, NULL },
mc_7 = { '7', NULL, NULL },
mc_6 = { '6', NULL, NULL },
mc_1 = { '1', NULL, NULL },
mc_2 = { '2', NULL, NULL },
mc_3 = { '3', NULL, NULL },
mc_4 = { '4', NULL, NULL },
mc_5 = { '5', NULL, NULL },
mc_Odash = { '\0', &mc_9, &mc_0 },
mc_Odot = { '\0', &mc_8, NULL },
mc_Q = { 'q', NULL, NULL },
mc_Z = { 'z', &mc_7, NULL },
mc_Y = { 'y', NULL, NULL },
mc_C = { 'c', NULL, NULL },
mc_X = { 'x', NULL, NULL },
mc_B = { 'b', &mc_6, NULL },
mc_J = { 'j', NULL, &mc_1 },
mc_P = { 'p', NULL, NULL },
mc_L = { 'l', NULL, NULL },
mc_Udash = { '\0', NULL, &mc_2 },
mc_F = { 'f', NULL, NULL },
mc_V = { 'v', NULL, &mc_3 },
mc_H = { 'h', &mc_5, &mc_4 },
mc_O = { 'o', &mc_Odot, &mc_Odash },
mc_G = { 'g', &mc_Z, &mc_Q },
mc_K = { 'k', &mc_C, &mc_Y },
mc_D = { 'd', &mc_B, &mc_X },
mc_W = { 'w', &mc_P, &mc_J },
mc_R = { 'r', &mc_L, NULL },
mc_U = { 'u', &mc_F, &mc_Udash },
mc_S = { 's', &mc_H, &mc_V },
mc_M = { 'm', &mc_G, &mc_O },
mc_N = { 'n', &mc_D, &mc_K },
mc_A = { 'a', &mc_R, &mc_W },
mc_I = { 'i', &mc_S, &mc_U },
mc_T = { 't', &mc_N, &mc_M },
mc_E = { 'e', &mc_I, &mc_A },
mc_root = { '\0', &mc_E, &mc_T };
int main()
{
char ch;
std::string seq;
const morse_node *loc = &mc_root;
int spcount = 0;
bool run = true;
while(run && std::cin.get(ch)) {
switch(ch)
{
case '.':
case '-':
spcount = 0;
seq += ch;
loc = ch == '.' ? loc->dot : loc->dash;
if(!loc) {
std::cerr << "Invalid sequence: " << seq << '\n';
seq.clear();
loc = &mc_root;
}
break;
case '\n':
++spcount;
case '\t':
++spcount;
case ' ':
++spcount;
if(loc != &mc_root) {
if(loc->ch == '\0') {
std::cerr << "Invalid sequence: " << seq << '\n';
} else {
std::cout << loc->ch;
}
}
if(spcount >= 3) {
std::cout << '\n';
spcount = 0;
} else if(spcount >= 2) {
std::cout << ' ';
spcount = 0;
}
seq.clear();
loc = &mc_root;
break;
case '!':
run = false;
break;
default:
std::cerr << "Invalid character: " << ch << '\n';
seq.clear();
loc = &mc_root;
break;
}
}
if(loc->ch != '\0') {
std::cout << loc->ch;
}
std::cout << std::endl;
}
(Note: it uses pointers. But then, strictly speaking, so do all of your attempts.)