I was solving just simple task for learning purposes. Task: Encode the given string with morse code, return the encoded string. Problem: 3 spaces denoting 1 space between words in morse code are lost when the string is split into tokens.
The result should be: "HEY JUDE" Current result: "H EYJ U D E"
During the solution my approach changed 3 times
- i was iterating all the symbols from original msg and vocabulary one by one
- i was building a state machine with like 7 states And finally i found the best approach from my point of view
- Splitting the giving string into the tokens and then compare with strcmp with the vocabulary
But the problem is that during the splitting with strtok i am missing the 3 spaces which should be exactly the "pointer" to where exactly should i put the spaces during the encoding procedure. I came out with the solution of that thing - check out the find_space_positions functions. But its working not completely correct and i don't understand why.
Could please help me to understand why the find_space_positions is not working the way it supposed to be? How to make it work the way i want to ?
What is the better approach to do such stuff in C ?
Here is the code:
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include<stdio.h>
const char *morse[55] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", ".-.-.-", "--..--", "..--..", ".----.", "-.-.--", "-..-.", "-.--.", "-.--.-", ".-...", "---...", "-.-.-.", "-...-", ".-.-.", "-....-", "..--.-", ".-..-.", "...-..-", ".--.-.", "...---..."};
const char *ascii[55] = {"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", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", ",", "?", "'", "!", "/", "(", ")", "&", ":", ";", "=", "+", "-", "_", "\"", "$", "@", "SOS"};
char input[] = ".... . -.-- .--- ..- -.. .";
static uint16_t msg_iter = 0;
static uint16_t voc_word_iter = 0;
static uint16_t voc_word_chr_iter = 0;
static uint16_t iter = 0;
static char buf[20] = "";
bool find_space_positions (const char* morse_code, uint16_t token_counter, uint16_t len ) {
uint16_t space_counter = 0;
for (uint16_t i = 0; i <len; i++){
printf("%c\n", morse_code[i]);
if (morse_code[i] == ' ') {
space_counter++;
printf("%d+++ \n", space_counter);
}
else if (space_counter == token_counter) {
if (morse_code[i + 1] == ' ' && morse_code[i + 2] == ' ') {
return true;
}
else {
return false;
}
}
}
}
void decode_morse(const char *morse_code) {
uint16_t input_len = strlen(morse_code);
char *word = strtok(morse_code, " ");
uint16_t token_number = 1;
while (word != NULL) {
for (int voc_word_iter = 0; voc_word_iter < 55; voc_word_iter++) {
if (strcmp(word, morse[voc_word_iter]) == 0) {
if (find_space_positions(input,token_number, input_len )) {
buf[iter] = ' ';
iter++;
}
buf[iter] = *ascii[voc_word_iter];
iter++;
break;
}
}
word = strtok(NULL, " ");
token_number++;
}
printf("%s\n", buf);
}
int main () {
decode_morse(input);
return 777;
}
". ." v
"But its working not completely correct and i don't understand why."
It's difficult to diagnose optimistic code that is doing the wrong thing in the wrong way. However, it's worth noting that the helper function
find_space_positions()tries hard to find the smoking remains of what once was 3 consecutive spaces. Unfortunately, this helper function is counting the remaining pair of SP's as 2 when it searching fortoken_numthat is only 1 (for each word...). It's all a bit too wrong to correct.As directed by "What is the better approach to do such stuff in C ?" the following is offered as implementing the approach outlined in the comments:
Note that each function does one thing. The hierarchy approach follows the KISS principle.
This does output "HEY JUDE".
- .- -.- . .- ... .- -.. -.-. --- -.. . .- -. -.. -- .- -.- . .. - -... . - - . .-.EDIT:
As a bonus, here is your
morse[]andascii[]arrays merged into a single array. Using this, all that is needed is to alter thestrcmp()in the function/loop that is searching for a match:(Needless to say, the correctness or completeness of the codes you provided have not been double-checked. Caveat emptor!)