A Morse Code filter probably has no practical use, but it’s a good programming exercise. The issue is how to deal with undefined character codes and otherwise present the output. My solution for this month’s Exercise involves interpreting standard input, discarding undefined information, and sending the results to standard output in a format that isn’t ugly.
A filter processes input one character at a time. The character must be defined as an integer, which is necessary to catch the EOF should input be redirected from a file. This task is handled in the main() function, provided in the skeleton offered:
while(1)
{
ch = getc(stdin);
if( ch==EOF )
break;
toMorse(ch);
}
Within the toMorse() function, characters are manipulated by the ctype.h
header functions as well as a standard if test:
- Use isalpha() to test for alphabetic characters and process.
- Use isdigit() to test for numbers 0 through 9 and process.
- Use an if condition to test for spaces and newlines.
For the isalpha() part of the code, the character is converted to uppercase as Morse Code is case-insensitive. The value 'A'
is subtracted from the result, which is used as an index into the morse_alpha[]
array. The matching string is output.
The isdigit() part of the code works the same as isalpha(), though the character need not be converted to uppercase and the index is used in the morse_digit[]
array.
When the space or newline are encountered (the final if test), a newline is output.
For all other characters, the code returns without generating any output.
Here is the full code for my solution, which is also published on GitHub:
#include <stdio.h>
#include <ctype.h>
void toMorse(char c)
{
char *morse_alpha[] = {
".-", "-...", "-.-.", "-..", ".", "..-.",
"--.", "....", "..", ".---", "-.-", ".-..",
"--", "-.", "---", ".--.", "--.-", ".-.",
"...", "-", "..-", "...-", ".--", "-..-",
"-.--", "--.."
};
char *morse_digit[] = {
"-----", ".----", "..---", "...--", "....-",
".....", "-....", "--...", "---..", "----."
};
int m;
if( isalpha(c) )
{
/* Morse is case-insensitive */
c = toupper(c);
m = c - 'A';
printf("%s ",morse_alpha[m]);
}
else if( isdigit(c) )
{
m = c - '0';
printf("%s ",morse_digit[m]);
}
else if( c==' ' || c=='\n' )
{
putchar('\n');
}
else
return;
}
int main()
{
int ch;
while(1)
{
ch = getc(stdin);
if( ch==EOF )
break;
toMorse(ch);
}
return(0);
}
The ctype.h
header file included in my solution isn’t included in the original skeleton. It’s possible to concoct a solution without using any ctype functions, but I’m lazy. Further, much of the code could be condensed, though I favor readable code over brief code.
If your solution results in Morse Code output based on all forms of input, filtering out any undefined characters, consider your solution worthy. Even if you think this challenge is too easy, it’s always good to hone your programming skills. You never know when a solution to a simple problem can offer insight into a larger more complex puzzle. Such is the nature of computer programming.
I’m sure this is way overkill and can definitely be coded more efficiently, but I’m just very glad I got a solution on my own: Beware, lots of comments (to help me, later on).
Crud! I forgot all about the “isdigit” or “isalpha” functions!
Thanks for sharing your solution. Don’t worry about missing out on the ctype functions; they accomplish the same thing you did.
For help in posting code, refer to this page: https://c-for-dummies.com/blog/?page_id=1274