Morse to text

I have a problem with translating morse to text, and I have no clue how to overcome this obstacle. Here is my current code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

string t[] = { "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N",
    "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Å", "Ä", "Ö" };

string m[] = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",
    ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
    "...-", ".--", "-..-", "-.--", "--..", ".--.-", ".-.-", "---." };

string MorseTillText(string morse)
{
    string temp;
    string text = "";
    for(int i = 0; i < morse.length(); i++)
    {
        while(morse[i] != " ")
            temp.append(morse[i]);

        if(temp == " ")
            text += " ";
        text += t[temp - m[0]];
    }
    return text;
}

int main()
{
    stringstream sStream;
    string text;
    getline(cin, text);
    sStream << text;
    cout << "Morse: ";
    while(sStream >> text)
        cout << MorseTillText(text);
}


I have zero ideas how to make it check "words" instead of 1 character at the time. Now I get the error "error: ISO C++ forbids comparison between pointer and integer" So I don't know what to try now. Anyone that can help with some ideas?
Wow! That's a pretty tricky problem. Is this some kind of assignment? Where from?
Yah it's a assignment and I prefer ideas over code, so for as far as possible don't post code.
So ideas or hints on what I could read to solve this nut would be helpful.

With ideas I mean stuff like "You should read about this ... and this ..." better for my learning then showing code :p and I wont end up with a lazy-urge-to-copy-paste
Last edited on
Processing it character by character is the way to go. Like a finite state machine, you could keep track of the state until you identify what character to replace an accumulated string with. For example, grab the first character and filter your possible matches down to the ones that start with that character. Then grab the second character and filter, etc. until there is only 1 possible replacement.
My code did check char for char at first, but morse are more then 1 char. "A" is .- in morse, so checking 1 char at the time wont work I would end up with a bunches of "E"s (. = e)

My guess is that I need to make a temp string that add one char at the time until it meets a blank and then compare with the morsecode to get the right number and fetch the char from t.

ex: check morse ".", "-", " " stop check for ".-" in m[], get position, fetch alphabetic char from t[], put it in text.

I have already made the "text to morse" function and that works perfect it's the morse to text that eludes me :(
Last edited on
Forgive me, I wasn't thinking about whitespace. If the morse code is separated by whitespace (I guess it would have to be), this assignment is much more simple than I thought.

Tokenize the whitespace-delimited string and perform the replacements. That's all. I was [incorrectly] thinking that you would have to accumulate characters until you match one of the valid morse codes.

Consider:
1
2
3
4
5
6
7
8
9
10
11
string translate( const string & code )
{
    // replace morse code with appropriate letter
}
//..
fstream f( "code.txt" );
string code;
while( f >> code )
{
    cout << translate( code );
}
you could take the lazy path. create a stringstream from the Morse code string and a map with codes and their chars. Then while(mystringstream >> tempstr) result.append( mymap[tempstr] ); (though for error checking you'd have to use map::find).
Though of course that would be sort of missing the point.. (edit: would it?)
Last edited on
Your code isn't that pretty much the same as my code except that I doesn't use a const in the function head, and instead of checking a file I check the users input. Or am I missing something?

My code shortened:
1
2
3
4
string MorseTillText(string morse)
{
// ...
}

and
1
2
3
4
5
6
7
stringstream sStream;
    string text;
    getline(cin, text);
    sStream << text;
    cout << "Morse: ";
    while(sStream >> text) // I just didnt use the { } 
        cout << MorseTillText(text);


In my MorseTillText func I use this
1
2
while(morse[i] != " ")
            temp.append(morse[i]);
as append is suppose to put the character last in temp as long as it's not a whitespace. When it meet the whitespace I want it to leave the while, and add the appropriate letter from t[]. But with my code I ended up with a error I forgot to add in my original post:
1
2
3
4
5
6
7
8
I:\morse\morse.cpp||In function `std::string MorseTillText(std::string)':|
I:\morse\morse.cpp|45|error: ISO C++ forbids comparison between pointer and integer|
I:\morse\morse.cpp|46|error: invalid conversion from `char' to `const char*'|
I:\morse\morse.cpp|46|error:   initializing argument 1 of `std::basic_string<_CharT, _Traits, 
_Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::append(const _CharT*) [with _CharT = 
char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]'|
I:\morse\morse.cpp|51|error: no match for 'operator-' in 'temp - m[0]'|
||=== Build finished: 4 errors, 0 warnings ===|


I am sorry if I miss something obvious I have been at this all day and is pretty tired.

I will take a look at the map "thingy" hamsterman thanks for the tip
Last edited on
I:\morse\morse.cpp|45|error: ISO C++ forbids comparison between pointer and integer|
Oh. I didn't notice that one. morse[i] != " ". " " is a const char* to a string { ' ', '\0' }. morse[i] is a char. You can't compare those two. You meant morse[i] != ' '.

I:\morse\morse.cpp|46|error: invalid conversion from `char' to `const char*'|
string::append appends a string to another string. You only want to append one char, so use string::push_back.

I:\morse\morse.cpp|51|error: no match for 'operator-' in 'temp - m[0]'|
temp is a string, m[0] is a char. What are you trying to do here?

map would simplify things greatly, but you don't have to do that. You could simply do
1
2
for(int i = 0; i < sizeof(m)/sizeof(m[0]); i++)//for every element in m,
    if(morse == m[i]) return t[i];//if it matches the code you have, return the appropriate char. 
Last edited on
Topic archived. No new replies allowed.