Morse to text

Nov 12, 2010 at 8:18pm
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?
Nov 12, 2010 at 8:26pm
Wow! That's a pretty tricky problem. Is this some kind of assignment? Where from?
Nov 12, 2010 at 8:33pm
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 Nov 12, 2010 at 8:46pm
Nov 12, 2010 at 8:47pm
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.
Nov 12, 2010 at 8:53pm
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 Nov 12, 2010 at 8:55pm
Nov 12, 2010 at 9:01pm
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 );
}
Nov 12, 2010 at 9:02pm
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 Nov 12, 2010 at 9:03pm
Nov 12, 2010 at 9:19pm
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 Nov 12, 2010 at 9:24pm
Nov 14, 2010 at 9:56am
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 Nov 14, 2010 at 9:58am
Topic archived. No new replies allowed.