Thread: Homework- Morse Code output problem

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    19

    Homework- Morse Code output problem

    I have been working on this for about 5 hours now and I can't figure this out.. Its my first semester in Computer Engineering with no programming experience.

    So, the program is supposed to supply a space between each letter in morse code and 3 spaces between each word. However, the program is not displaying the first character in morse code letter, and randomly displays letters or symbols instead of the characters its supposed to. Here is the code. (also, I realize I don't need all the extra stuff like function calls, but I want to use them for practice)

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define STR 1000
    
    void English_to_Morse(char *line, int size)
    {
       int j=0, a;
       char str[STR];
       
      
       for(a=0; a<size; a++)
       {
          switch(toupper(line[a]))
          {
          case 'A':
            str[j]='.';
            str[j++]='-';
            str[j++]=' ';
              break;
           
          case 'B':
            str[j]='-';
            str[j++]='.';
            str[j++]='.';
            str[j++]='.';
            str[j++]=' ';
              break;
     
          case 'C':
              str[j]='.';
              str[j++]='-';
              str[j++]='.';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case 'D':
              str[j]='-';
              str[j++]='.';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case 'E':
              str[j]='.';
                 break;
     
            case 'F':
              str[j]='.';
              str[j++]='.';
              str[j++]='-';
              str[j++]='.';
              str[j++]=' ';
                break;
     
           case 'G':
              str[j]='-';
              str[j++]='-';
              str[j++]='.';
              str[j++]=' ';
                break;
     
           case 'H':
              str[j]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case 'I':
              str[j]='.';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case 'J':
              str[j]='.';
              str[j++]='-';
              str[j++]='-';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case 'K':
              str[j]='.';
              str[j++]='-';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case 'L':
              str[j]='.';
              str[j++]='-';
              str[j++]='.';
              str[j++]='.';
              str[j++]=' ';
              break;
     
            case 'M':
              str[j]='-';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case 'N':
              str[j]='-';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case 'O':
              str[j]='-';
              str[j++]='-';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case 'P':
              str[j]='.';
              str[j++]='-';
              str[j++]='-';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case 'Q':
              str[j]='-';
              str[j++]='-';
              str[j++]='.';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case 'R':
              str[j]='.';
              str[j++]='-';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case 'S':
              str[j]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case 'T':
              str[j]='-';
              str[j++]=' ';
                break;
     
            case 'U':
              str[j]='.';
              str[j++]='.';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case 'V':
              str[j]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case 'W':
              str[j]='.';
              str[j++]='-';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case 'X':
              str[j]='-';
              str[j++]='.';
              str[j++]='.';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case 'Y':
              str[j]='-';
              str[j++]='-';
              str[j++]='.';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case 'Z':
              str[j]='-';
              str[j++]='-';
              str[j++]='.';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case '0':
              str[j]='-';
              str[j++]='-';
              str[j++]='-';
              str[j++]='-';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case '1':
              str[j]='.';
              str[j++]='.';
              str[j++]='-';
              str[j++]='-'; 
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case '2':
              str[j]='.';
              str[j++]='.';
              str[j++]='-';
              str[j++]='-';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case '3':
              str[j]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]='-';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case '4':
              str[j]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]='-';
              str[j++]=' ';
                break;
     
            case '5':
              str[j]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case '6':
              str[j]='_';
              str[j++]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case '7':
              str[j]='-';
              str[j++]='-';
              str[j++]='.';
              str[j++]='.';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case '8':
              str[j]='-';
              str[j++]='-';
              str[j++]='-';
              str[j++]='.';
              str[j++]='.';
              str[j++]=' ';
                break;
     
            case '9':
              str[j]='-';
              str[j++]='-';
              str[j++]='-';
              str[j++]='-';
              str[j++]='.';
              str[j++]=' ';
                break;
            
            case ' ':
              str[j]=' ';
              str[j++]=' ';
              str[j++]=' ';
                break;    
        
          }
          j++;      
       }        
      
      
      
       printf("\n\t%s and size is %d\n", str, size-1);
       
    }   
    
    int main()
    {
       int len;
       char phr[STR];
       
       
       printf("\n\tEnter a phrase or word you want to be converted to Morse Code\n"
              "\tor a line of Morse Code you want to be converted to English\n\n");
       printf("\t");
      
       fgets(phr, STR, stdin);
       
       len=strlen(phr);
       
       English_to_Morse(phr, len);
       
        
       return 0;
       
    }

  2. #2
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Welcome to the forums, Reboot.Revival.

    Quote Originally Posted by Reboot.Revival View Post
    the program is supposed to supply a space between each letter in morse code and 3 spaces between each word.
    Note that because you supply a space after every letter and digit, and three spaces for an input space, you end up having four consecutive spaces between words.

    Quote Originally Posted by Reboot.Revival View Post
    Code:
            str[j]='.';
            str[j++]='-';
    The first line writes a dot at index j in str.
    The second line writes a dash at index j in str, then increments j.

    In other words, you should always have the post-increment when you add a new character into str, or you'll just overwrite the first character of each letter or digit you tried to add.

    Quote Originally Posted by Reboot.Revival View Post
    Code:
       printf("\n\t%s and size is %d\n", str, size-1);
    At this point, str is just a character array, with j characters in it. In C, strings are terminated with a NUL character, '\0'. You can form the contents of your buffer into a string by terminating the contents,
    Code:
        str[j] = '\0';
    before you try to print it.

    Quote Originally Posted by Reboot.Revival View Post
    Code:
       fgets(phr, STR, stdin);
    fgets() returns either the pointer to phr, or NULL if an error occurs, or if there is no more input. You don't bother checking the return value, so your program may actually have garbage in phr at that point (because fgets() does not touch the contents then).

    I'd strongly suggest you check that fgets() does not return NULL. If it does, tell the user there was no more input, and exit the program.

    Lastly, toupper() is declared in <ctype.h>, so you might wish to #include that too.

    Other than the above, it looks like a very good effort! It seems you even enabled compiler warnings, and took care of those first. Very good!

  3. #3
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Code:
    #include <ctype.h>
    ...
    toupper()
    Code:
    case 'T':
              str[j++]='-'; /* First element is '-', and then increment j */
              str[j]=' ';    /* Second element is ' '  - The j++ is done after the switch statement*/
                break;
    [edit] Too slow [/edit]
    Fact - Beethoven wrote his first symphony in C

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Look at how I changed this case for 'T'
    Code:
            case 'T':
              str[j++]='-';
              str[j++]=' ';
                break;
    Edit: Way to slow!
    Edit2: @Click_here did you test with the word "Test" also.

    Tim S.
    Last edited by stahta01; 11-25-2012 at 08:57 PM.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  5. #5
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Whoops, missed one!

    Quote Originally Posted by Reboot.Revival View Post
    Code:
            case ' ':
              str[j++]=' ';
              str[j++]=' ';
              str[j++]=' ';
                break;    
        
          }
          j++;
    That j++; line there is a bug.

    You see, if you increment j, you're basically saying "I added a new character to str". In a way, j specifies the length of the data in str, because it says where the next character will be added (if one will be added).

    If you have a non-digit, non-letter character in line, then you end up adding an unspecified character to str, as you only increase j!

    Also, you don't need toupper() at all. Instead, you can use
    Code:
          switch (line[a])
          {
          case 'A':
          case 'a':
            str[j++]='.';
            str[j++]='-';
            str[j++]=' ';
              break;
            
          case 'B':
          case 'b':
            str[j++]='-';
            str[j++]='.';
            str[j++]='.';
            str[j++]='.';
            str[j++]=' ';
              break;
    because in C, the case just tells the switch statement where to continue execution; it does not stop any previous cases from continuing ("falling through") that point. You use break; for that.

  6. #6
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Quote Originally Posted by stahta01
    Edit2: @Click_here did you test with the word "Test" also.
    Guilty as charged.
    Fact - Beethoven wrote his first symphony in C

  7. #7
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    Thanks for the advice. I have class this morning and work afterwords so I will try it out this evening.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    So in other words, the "break" was broken? lol!

  9. #9
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    @ Nominal Animal
    The j++ line isnt a bug, I added that in there so I wouldnt have to increment every j in all the case lines. Every loop starts at the next index because of that one line. Also I use toupper to reduce the writting, again. No need to write "case 'a':" etc in lowercase for every case when I can just convert the letters to upper case.

    To everyone else thanks for the help.

    I just went in and changed the post increments to pre increments and now it works fine.
    Code:
    for(a=0; a<size; a++)
       {
          switch(toupper(line[a]))
          {
          case 'A':
            str[j]='.';
            str[++j]='-';
            str[++j]=' ';
              break;
           
          case 'B':
            str[j]='-';
            str[++j]='.';
            str[++j]='.';
            str[++j]='.';
            str[++j]=' ';
              break;
    Also @Click_here
    Despite being a new computer engineering student, I have been running Ubuntu for a few years and recently switched to Mint. I use Gedit and GCC for compling. I don't know if it is different for linux than windows but I was told <stdlib.h> included what was needed for isalpha, isdigit, toupper, and tolower. I don't have <ctype.h> in there and it runs fine, and doing a test just with toupper on a random string prints it out in all caps.

    now to reverse the process from morse code to english.
    Last edited by Reboot.Revival; 11-26-2012 at 07:55 PM.

  10. #10
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    It's nice of your compiler to run toupper without ctype.h - However, you should be thinking "how do I make good transportable code".

    Most students just want to pass the subject and then forget about what they learnt - If this is you, don't worry about it.

    toupper is definitely in ctype.h and not in stdlib.h

    C11 standard - 7.4.2.2 The toupper function
    Synopsis
    1 #include <ctype.h>
    int toupper(int c);
    Description
    2 The toupper function converts a lowercase letter to a corresponding uppercase letter.
    Returns
    3 If the argument is a character for which islower is true and there are one or more
    corresponding characters, as specified by the current locale, for which isupper is true,
    the toupper function returns one of the corresponding characters (always the same one
    for any giv en locale); otherwise, the argument is returned unchanged.



    C89 - 4.3.2.2 The toupper functionSynopsis

    #include <ctype.h>
    int toupper(int c);

    ...



    C99 -7.4.2.2 The toupper function

    Synopsis

    #1
    #include <ctype.h>
    int toupper(int c);
    Fact - Beethoven wrote his first symphony in C

  11. #11
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by Reboot.Revival View Post
    @ Nominal Animal
    The j++ line isnt a bug
    It is. See what happens when the input string contains for example a question mark: you get garbage characters or truncated output instead of correct Morse code.

    Quote Originally Posted by Reboot.Revival View Post
    I just went in and changed the post increments to pre increments and now it works fine.
    Are you sure?

    Your j++ line is a bug, causing garbage to be included in the Morse code when the input string contains anything other than letters and digits.

    It masks another bug, which would otherwise eat the last Morse code symbol (dot or dash) from the string.

    Changing from post-increments to preincrements changes your j interpretation from "length" or "position for the next character" to something else -- I don't know what.

    You don't seem to care that your code is very fragile. Just do any random change that seems to make it work. Fine; I won't waste any more of my time either.

  12. #12
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    Im super stuck on this part. Any ideas. I need to convert alphas and digits and obviously switch won't work. This is my first assignment with strings so I am pretty stumped.

  13. #13
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Fact - Beethoven wrote his first symphony in C

  14. #14
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by Reboot.Revival View Post
    I use Gedit and GCC for compling. I don't know if it is different for linux than windows but I was told <stdlib.h> included what was needed for isalpha, isdigit, toupper, and tolower. I don't have <ctype.h> in there and it runs fine, and doing a test just with toupper on a random string prints it out in all caps.
    gcc complains about not including <ctype.h>:
    Code:
    $ cat foo.c
    #include <stdio.h>
    
    int main(void)
    {
        printf("%c\n", toupper('a'));
        return 0;
    }
    $ gcc -Wall foo.c
    foo.c: In function ‘main’:
    foo.c:5:5: warning: implicit declaration of function ‘toupper’ [-Wimplicit-function-declaration]
    It's time to turn on the warnings. I suggest at least -Wall and -Wextra.

    Bye, Andreas

  15. #15
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    Thanks for all the help. My professor said she didnt want switch statements because it would take to long to grade so I had to scrap the whole thing and start over. I ended up with a cleaner program but I got stuck with it not ending after the conversion because a while loop wouldn't end. But otherwise it worked fine. I had to turn it in so that was the only bug. I would post it but I don't have it on this computer and my email attachment to myself for some reason didn't work.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Morse Code(Going the other way)
    By lilbo4231 in forum C Programming
    Replies: 21
    Last Post: 06-16-2011, 03:25 AM
  2. Problem with my morse code program
    By justin87 in forum C++ Programming
    Replies: 1
    Last Post: 10-21-2007, 05:23 PM
  3. Morse code conversion
    By viclaster in forum C Programming
    Replies: 6
    Last Post: 12-04-2003, 09:24 PM