C++ User-Input into Morse code

Hello Everyone,

I am trying to code, in C++, a program that will convert user input into Morse code. The mappings for the morse code will be received from two separate files, and the entire program will be broken up into 4 functions:

file input- if the file is not opened properly, there should be an error message to let the user know otherwise.

Character translation

the primary procession loop-that will read in the cin from the user and translate into Morse code

the main function

The text to be translated will be received from the cin from the user, as long as "quit" has not been entered by the user. Characters
read in from cin should be folded into upper case (input of a and A should both map to the Morse
code . - character sequence. A space character should map to a space character. A character that does
not map to Morse code (such as $) should be output in double quotes (such as "$" ) to indicate that the
text was not translated. Finally, any Morse code output should be separated by a space from other
output.

There should be no global variables

Here is what I have so far, there are comments to help make the code easier to read:
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// This program will translate a string of input from the user
// and translate this input into morse code
#include <iostream> 
#include <string> 
#include <cstdlib>
#include <fstream>
#include <cctype>
#include <cstring>
using namespace std;

string fileIO(string morsecode[], char morseletter[]);
// This will be the program that reads the information from the files and verifies that it opened properly
string charTranslate();
// This program should translate the input from the user into morse code, according to the file input
string getFromUser();
// this will recieve input from the user, fold all the characters to their uppercase value,
// and then pass it on to the function that will translate to morse code

int main()
{ 
	string morsecode[50];
	char morseletter[50];
	//arrays in main.. and you need to pass them to functions 
	fileIO(morsecode,morseletter);
	//print out the arrays and makes sure they match the file
	getFromUser();
	charTranslate();
	return 0;
}

string fileIO(string morsecode[], char morseletter[])
// this function will ask for the name of the file from the user and fill both arrays with the proper values.
// the first array will be filled with the characters, the second will hold the equivalent morse code translation.
// this function will return both arrays for later use?
{
	// the file has been opened, and this series of statements will verify whether the file was opened or not.
	ifstream file;
	string name;
	cout << "Enter in the name of the input file that contains the mappings " << endl;
	cin >> name;
	file.open(name.c_str());
	if (file.fail())
	{
		cout << "The file could not be opened." << endl;
	}
	// this is the part where the arrays are filled with their respective values
	int numlines;
	file >> numlines;
	
	
	/*
	// this should contain the chars to be translated
	char* morseletter = new char[numlines];
	// this should contain the strings of morse code
	string * morsecode = new string[numlines];
	*/


	for (int i = 0; i < numlines; i++) {
		file >> morseletter[i];
		getline(file, morseletter[i], " ");
		file >> morsecode[i];
		getline(morsecode[i]);

		/*
		getline(file, morseletter[i]," "); //delimit by space. 
		getline(morsecode[i]);
		*/

	}

	file.close();
	return 0;
	// this function will return   back to function main so that the program can continue.
}

string getFromUser()
// this function will receive the sentence to be translated from the user.
// if the sentence is not "quit", the function will pass this input onto the translator function.
// if the sentence is "quit", the function will end.
// this function will also fold all the lower case values to their uppercase values
{
	string input;
	cout << "Enter the string to be translated (or quit to exit)" << endl;
	getline(cin, input);
	// this is where the function will receive the input to be translated from the user

	// the string obtained must be folded up to uppercase letters.

	// this is where we will validate the phrase, either to continue the program, or end it.
	if (input == "quit")
	{
		return 0;// end the program
	}
		return 0;
}

string charTranslate()
// this function will translate the input from the user into the proper morse code. 
// if the character to be translated cannot be found in the file, this function will
// print out the character surrounded by quotation marks.
// ex. 2 will be "2" if 2 cannot be found from the input file.
{
	return 0;
}

I realize this isn't much, but I could really use some help with this.
Last edited on
Please edit your post and use code tags. Highlight the code and press the "<>" button on to the right of the edit window.

What is the format of the file that contains the morse code? This doesn't look right:
1
2
3
4
        file >> morseletter[i];
        getline(file, morseletter[i], " ");
        file >> morsecode[i];
        getline(morsecode[i]);


In getFromUser() what will you do if the input is "quit"? You're supposed to exit the program. To make this easier I think you should do that check inside the main() function instead.

You need to pass some parameters to "charTranslate". At a minimum, you need to pass the input string and the morsecode array.

This is what the first file looks like:

39
, --..--
. .-.-.-
? ..--..
0 -----
1 .----
2 ..---
3 ...--
4 ....-
5 .....
6 -....
7 --...
8 ---..
9 ----.
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 --..

And here is the second file

50
, --..--
. .-.-.-
? ..--..
' .----.
! -.-.--
( -.--.
) -.--.-
: ---...
; -.-.-.
= -...-
+ .-.-.
- -....-
" .-..-.
@ .--.-.
0 -----
1 .----
2 ..---
3 ...--
4 ....-
5 .....
6 -....
7 --...
8 ---..
9 ----.
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 --..
I'd change the data a little bit. Make morsecode map characters to the corresponding morse code string. You can get the max value of a character from limits:

1
2
#include <limits>
string morsecode[std::number_limits<char>::max()+1];


Now given a character ch, the morsecode for it is simply morsecode[ch]

Now think about the parameters and return value for fileIO. I'd return a bool that says whether it succeeded or failed. The only parameter you need to pass is the morsecode array:
bool fileIO(string morecode[]);

Inside fileIO, read the character and string from each line and then set morsecode appropriately.
I'd change the data a little bit. Make morsecode map characters to the corresponding morse code string.

That's a good suggestion, but why not just use a couple of std::maps. Ie:

1
2
std::map<std::string, char> morse_to_char;
std::map<char, std::string> char_to_morse;


Then when you read the files you can just fill in these maps with the proper key, value pair,

Reading the first file with the char_to_morse map pass as a reference parameter:

1
2
3
4
char alpha;
std::string morse;
file_io >> std::ws >> alpha >> morse;
char_to_morse[alpha] = morse;


Reading the second file with morse_to_char parameter:
1
2
3
4
char alpha;
std::string morse;
file_io >> std::ws >> alpha >> morse;
morse_to_alpha[morse] = alpha
;

Of course you would need to be reading the file in a loop and read the "number_of_elements" before the loop.

Then "translating" to and from morse would be easy, just use the correct map and "search" for the map key and then print that map value.


That's a good suggestion, but why not just use a couple of std::maps.

There is no requirement to map from morse code to characters, only from char to morse code. For that, an std::map would be a lot more code and a lot slower than a simple array.
There is no requirement to map from morse code to characters, only from char to morse code. For that, an std::map would be a lot more code and a lot slower than a simple array.

I'd find a map far more intuitive for that, than an array. It's exactly the sort of thing maps were designed for. I very much doubt performance is an issue here.

And if there were a requirement for a 2-way conversion, Boost bimap is a powerful class:

http://www.boost.org/doc/libs/1_60_0/libs/bimap/doc/html/index.html

Last edited on
I'd find a map far more intuitive for that, than an array.

With a map, you'd write:
1
2
3
std::map<char,std::string> morseCode;  char -> morse code
...
morseCode[ch] = str;

and with an array it would be
1
2
3
string moreCode[numeric_limits<char>::max()+1];  // char -> morse code
...
morseCode[ch] = str;

I don't see how one is more intuitive than the other.

It's exactly the sort of thing maps were designed for.
This is mapping a small integral value to a string. The only thing that maps have over arrays in this case is that the array would be sparse. Would the array data take less space than a map? That's hard to say. The map has the overhead associated with the nodes (at least 2 pointers) while the array has the overhead of empty strings. If space is an issue, I'd actually use a 2D array of char because the strings are so small and they don't change.

In terms of the code size and run time there is no comparison. It only takes a couple of instructions to access an element in an array. With a map you have to work your way down a tree that will be 5-6 nodes deep. Whether that time and code space matters depends on the hardware and application, but programmers should choose small and fast solutions when they are just as clear and larger slower ones.

And if there were a requirement for a 2-way conversion, Boost bimap is a powerful class:

Good point.

MikeyBoy, you are experienced enough to know all of this already and to weigh the factors appropriately. My response is intended for others who might be reading along.
Topic archived. No new replies allowed.