diff --git a/main.c b/main.c index 891f417..f8c23c4 100644 --- a/main.c +++ b/main.c @@ -42,44 +42,35 @@ int main(int argc, char *argv[]){ if (convertFromMorse){ char* inputString; - char* wordToken; - char* letterToken; + char* outputString; // for every line in the input, until the end of file while ((getline(&inputString, &buflen, stdin))!=EOF){ - // find the next double space (produces in this program by default when outputting morse code) - wordToken = multi_tok(inputString, " "); - // While there is another block of text after a double space - while (wordToken){ - // find the next space or newline (newlines are not consumed by the getline function) - letterToken = strtok(wordToken, " \n"); - // while there is another block of text after a space (a newline will not have text after it, as we're using getline) - while (letterToken){ - // convert morse to ascii - reverse_morse(letterToken); - // set letterToken to new string after NEXT space/newline - letterToken = strtok(NULL, " \n"); - } - // set word token (all the characters that make up a word in morse) to the next block after a double space - wordToken = multi_tok(NULL, " "); - // this puts a space after every morse converted character. - // because strtok consumes the space it is not printed, or passed around - printf(" "); - } - // add a newline for every line consumed by getline - printf("\n"); + int stringLen = strlen(inputString); + + // This effectively strips the newline off the string + if (inputString[stringLen-1] == '\n'){ + inputString[stringLen-1] = '\0'; + } + + outputString = morse_to_string(inputString); + printf("%s\n", outputString); // force-flush the input buffer just in case the user is in interactive mode fflush(stdin); } } else { char* inputString; + char* outputString; // for each line of input while ((getline(&inputString, &buflen, stdin))!=EOF){ - // print the morse code of the line - // by default it is passthrough, meaning any non [a-zA-Z0-9] characters are printed as they are. - // the only exception is dashes and dots, which are removed from the ouptut to avoid confusing the input veriosn of the program - print_morse(inputString, isSlow, addLetterBeforeMorse, dot_delay, dash_delay); - // add a newline becuase it will not be printed otherwise - printf("\n"); + int stringLen = strlen(inputString); + + // This effectively strips the newline off the string + if (inputString[stringLen-1] == '\n'){ + inputString[stringLen-1] = '\0'; + } + + outputString = string_to_morse(inputString); + printf("%s\n", outputString); // force flush the buffer incase user is in interactive mode fflush(stdin); } diff --git a/morse.c b/morse.c index 2f69e27..ef3d87b 100644 --- a/morse.c +++ b/morse.c @@ -6,27 +6,31 @@ #include #include -#define NUM_OF_SYMBOLS 64 +#define NUM_OF_SYMBOLS 82 +#define MAX_MORSE_LENGTH 9 static const char SYMBOLS[NUM_OF_SYMBOLS] = { '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', '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', - ' ', '!'}; + '.', ',', '?', '\'', '!', '/', '(', ')', '&', ':', ';', '=', '+', '-', '_', '"', '$', '@', + ' '}; -// 7 spaces are needed to store the null terminator with the extended symbols :) -// C is fun? -static const char MORSE[NUM_OF_SYMBOLS][7] = { +static const char SYMBOL_ERROR = '~'; + +static const char MORSE[NUM_OF_SYMBOLS][MAX_MORSE_LENGTH] = { // A-Z ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", // a-z (same as above, but needed twice due to design choices) ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", // 0-9 "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", + // . , ? ' ! / ( ) & : ; = + - _ " $ @ EOF + ".-.-.-", "--..--", "..--..", ".----.", "-.-.--", "-..-.", "-.--.", "-.--.-", ".-...", "---...", "-.-.-.", "-...-", ".-.-.", "-...-", "..--.-", ".-..-.", "...-..-", ".--.-.", // space - "/", - // exclamation mark - "-.-.--"}; + "/"}; + +static const char* MORSE_ERROR = "........"; // This function returns a pointer to the morse code written above. // The genuis of this function feels amazing because I've never used C before, but I see why @@ -34,7 +38,7 @@ static const char MORSE[NUM_OF_SYMBOLS][7] = { // // I do not copy ANY data. The pointer returned points to the above array! const char* char_to_morse(char letter){ - const char* result_ptr; + const char* result_ptr = malloc(sizeof(char)*MAX_MORSE_LENGTH); bool result_set = false; for (int i = 0; i < NUM_OF_SYMBOLS; i++){ if (letter == SYMBOLS[i]){ @@ -43,7 +47,7 @@ const char* char_to_morse(char letter){ } } if (!result_set){ - result_ptr = ""; + result_ptr = MORSE_ERROR; } return result_ptr; } @@ -52,7 +56,7 @@ char* string_to_morse(char* string){ int string_len = strlen(string); // worse possible case is 8 times the length (assuming all numbers/punctuation, and adding spaces) // +1 for NULL terminator - char* result = malloc(sizeof(char)*string_len*8); + char* result = malloc(sizeof(char)*string_len*MAX_MORSE_LENGTH); // sets everything to null in the string, just in case there was data there previously. strcpy(result, ""); for (int i = 0; i < string_len; i++){ @@ -65,11 +69,18 @@ char* string_to_morse(char* string){ } const char morse_to_char(const char* morse){ - for (int i = 0; i < NUM_OF_SYMBOLS; i++){ + bool found_symbol = false; + char result; + for (int i = 0; i < NUM_OF_SYMBOLS && !found_symbol; i++){ if (strcmp(morse, MORSE[i]) == 0){ - return SYMBOLS[i]; + result = SYMBOLS[i]; + found_symbol = true; } } + if (!found_symbol){ + result = SYMBOL_ERROR; + } + return result; } char* morse_to_string(const char* morse_to_cpy){ @@ -84,113 +95,14 @@ char* morse_to_string(const char* morse_to_cpy){ //strcpy(result, ""); // split by the space character - char* morse_ptr = strtok(morse, " "); + char* morse_ptr = strtok(morse, " \n"); // until we reach the end of the string while (morse_ptr != NULL){ char char_to_add = morse_to_char(morse_ptr); // give the address of the single character to concatinate to result strcat(result, &char_to_add); // reset the morse ptr for the next section between a space - morse_ptr = strtok(NULL, " "); + morse_ptr = strtok(NULL, " \n"); } return result; } - -char *multi_tok(char *input, char *delimiter) { - static char *string; - if (input != NULL) - string = input; - - if (string == NULL) - return string; - - char *end = strstr(string, delimiter); - if (end == NULL) { - char *temp = string; - string = NULL; - return temp; - } - - char *temp = string; - - *end = '\0'; - string = end + strlen(delimiter); - return temp; -} - -void print_single_morse(char charToMorse, bool isSlow, bool addLetter, long dotDelay, long dashDelay){ - int sizeOfMorseCode; - bool isConvertable = false; - char convertedTo[6]; - - // Loop through every character in the list of letters - for (int j = 0; j < NUM_OF_SYMBOLS; j++){ - // If the character in the input string matches the character the character from the list - if (charToMorse == SYMBOLS[j]){ - strcpy(convertedTo, MORSE[j]); - sizeOfMorseCode = strlen(MORSE[j]); - isConvertable = true; - } - } - - if (addLetter){ - printf("(%c)", charToMorse); - } - if (isConvertable){ - if (isSlow){ - // loop through all the characters in the morse string - for (int i = 0; i < strlen(convertedTo); i++){ - printf("%c", convertedTo[i]); - // flush buffer to force visible slow writing - fflush(stdout); - if (convertedTo[i] == '-'){ - // usleep is a microseconds - usleep(dashDelay); - } else if (convertedTo[i] == '.'){ - usleep(dotDelay); - } - } - // print a space after the squence of morse code characters - printf(" "); - // if not slow - } else { - printf("%s ", convertedTo); - } - // if not convertable - } else { - if (charToMorse == '-' || charToMorse == '.'){ - } else { - printf("%c", charToMorse); - } - } -} - -void print_morse(char* strToMorse, bool isSlow, bool addLetter, long dotDelay, long dashDelay){ - int sizeOfInputString; - sizeOfInputString = strlen(strToMorse); - - // Loop through every character in the input string - for (int i = 0; i < sizeOfInputString; i++){ - print_single_morse(strToMorse[i], isSlow, addLetter, dotDelay, dashDelay); - } -} - -void reverse_morse(char* morseToNormalize){ - bool isConvertable = false; - char convertedChar; - - // go through every morse encoding - for (int i = 0; i < NUM_OF_SYMBOLS; i++){ - // if the morse code is euqal to the input string - if (strcmp(MORSE[i], morseToNormalize) == 0){ - isConvertable = true; - convertedChar = SYMBOLS[i]; - } - } - if (isConvertable){ - printf("%c", convertedChar); - // if not convertable to a normal character [A-Z0-9] print the character the stirng the way it is. - } else { - printf("%s", morseToNormalize); - } -} diff --git a/morse.h b/morse.h index 8cb7562..9d4ec2e 100644 --- a/morse.h +++ b/morse.h @@ -2,10 +2,5 @@ const char * char_to_morse(char letter); char * string_to_morse(char* string); -char * from_morse(char* string); const char morse_to_char(const char* morse); char * morse_to_string( const char* morse); - -void print_morse(char* string, bool b1, bool b2, long s1, long s2); -void reverse_morse(char* string); -char *multi_tok(char *input, char *delimiter); diff --git a/test.c b/test.c index adef2ec..80e549c 100644 --- a/test.c +++ b/test.c @@ -204,6 +204,7 @@ void test_morse_to_string(){ assert_mts("- .- .-.. -.-", "TALK"); assert_mts("- .- ... -.- / -- .- ... - . .-.", "TASK MASTER"); assert_mts("- .- .-. ..-. / -- .- .-.. .- -.- --- ...-", "TARF MALAKOV"); + assert_mts("- .- ..-", "TAU"); } void all_tests(){