Thread: i've written a simple code to convert text to morse..need some advise.

  1. #1
    Registered User
    Join Date
    Nov 2005
    Posts
    41

    i've written a simple code to convert text to morse..need some advise.

    Hi guys,

    It's me again . I've written a simple code to convert some text to morse code....

    after few days of fooling around with C code, i realised i often stumbled on the usage of pointers. i've always asked myself: im dealing with strings. Should i use arrays? or use pointers? whenever i tried pointers, it failed, hence i tried the array method instead.... Seems that im still confused with basic concepts of pointers and strings..

    Here are my codes. For your kind inputs and corrections please..

    I've some queries here:
    1. Under the *toMorse(char s[]) function, i've declared a static variable x[1024] which will be returned by the function. It will store the morse conversion. How do I convert 'x' to use pointers? Because I do not want to limit 'x' to size of 1024. But when ever i tried to implement 'x' via pointer methods, i would be pulling my hair off....

    2. I believe toUpper() function can be changed to using pointers stead.. I've pulled off a wad of hair earlier trying to use pointers..

    I've not learn how to walk properly and yet I'm trying to fly..


    Code:
    /*
    References: 
    http://en.wikipedia.org/wiki/Morse_code
    http://www.techonthenet.com/ascii/chart.php
    http://cprogramming.com 
    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   ----.
    Fullstop   .-.-.-
    Comma   --..--
    Query   ..--..
    Space /
    Period [.] 	ˇ - ˇ - ˇ -
    Comma [,] 	- - ˇ ˇ - -
    Question mark [?] 	ˇ ˇ - - ˇ ˇ
    Apostrophe ['] 	ˇ - - - - ˇ
    Exclamation mark [!] 	- ˇ - ˇ - -
    Slash [/] 	- ˇ ˇ - ˇ
    Parentheses ( ) 	- ˇ - - ˇ -
    Ampersand [&] 	ˇ ˇˇˇ
    Colon [:] 	- - - ˇ ˇ ˇ
    Semicolon [;] 	- ˇ - ˇ - ˇ
    Double dash [=] 	- ˇ ˇ ˇ -
    Fraction bar 	- ˇ ˇ - ˇ
    Hyphen [-] 	- ˇ ˇ ˇ ˇ -
    Underscore [_] 	ˇ ˇ - - ˇ -
    Quotation mark ["] 	ˇ - ˇ ˇ - ˇ
    "@" (commat) 	ˇ - - ˇ - ˇ
    */
    #include <stdio.h>
    
    void toUpperCase(char s[]);
    char *toMorse(char s[]);
    
    int main(int argc, char *argv[])
    {
      char *morse; 
      char s[]="sos call 911";
      toUpperCase(s);
      morse = toMorse(s);
      printf("%s",morse);
      return 0;
    }
    
    char *toMorse(char s[])
    {
    static char x[1024];
    char c[][37] = {
                    ".-",       /* 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*/
    		};
    int i=0;  
    while(s[i]!='\0')
    {
     if(s[i]>=65 && s[i]<=90)
     {
      strcat(x,c[s[i++]-65]);
      strcat(x," ");
     }
     else if(s[i]>=48 && s[i]<=57)
     {
      strcat(x,c[s[i++]-22]);      /*26-35 is the number range of c[][]..*/
      strcat(x," ");
     }
     else if(s[i]==32)
     {
      strcat(x,"/ ");
      i++;
     }
     else                                        
      i++;         /*i've only managed the alphabets and the numbers....*/
    } 
      return x; 
    }
    
    void toUpperCase(char s[])
    {
        int i=0;
        while(s[i]!='\0')(s[i]>=97 && s[i]<=122)?s[i++]-=32:s[i++];
    }
    Last edited by stevong; 11-20-2005 at 10:37 AM.

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    New Delhi
    Posts
    40
    1. Under the *toMorse(char s[]) function, i've declared a static variable x[1024] which will be returned by the function. It will store the morse conversion. How do I convert 'x' to use pointers? Because I do not want to limit 'x' to size of 1024. But when ever i tried to implement 'x' via pointer methods, i would be pulling my hair off....
    You'll need to learn dynamic memory allocation to acheive that, I suggest you read on that topic, you can look up your compiler docs for malloc(), that's one function that facilitates dynamic memory allocation.

    Code:
    #include <stdlib.h>
    
    int main(void)
    {
    	
    	char *string;
    	int size=10;
    
    	string=malloc(size * sizeof(*string));
    	
    	return 0;
    }
    The above code dynamically creates a character array of 10 chars. You can then access it like any other array,

    eg:- string[0]='a' etc
    Thanks,
    Sahil

  3. #3
    Registered User
    Join Date
    Nov 2005
    Posts
    41
    Quote Originally Posted by sahil_m
    You'll need to learn dynamic memory allocation to acheive that, I suggest you read on that topic, you can look up your compiler docs for malloc(), that's one function that facilitates dynamic memory allocation.

    Code:
    #include <stdlib.h>
    
    int main(void)
    {
    	
    	char *string;
    	int size=10;
    
    	string=malloc(size * sizeof(*string));
    	
    	return 0;
    }
    The above code dynamically creates a character array of 10 chars. You can then access it like any other array,

    eg:- string[0]='a' etc
    Thanks!!!

    Do i have to destroy string[] after i've used it?

  4. #4
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Of course. Always free your memory at the end of the program when you dynamically allocate them.
    Sent from my iPadŽ

  5. #5
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
    int i=0;  
    while(s[i]!='\0')
    {
     if(s[i]>=65 && s[i]<=90)
     {
      strcat(x,c[s[i++]-65]);
      strcat(x," ");
     }
     else if(s[i]>=48 && s[i]<=57)
     {
      strcat(x,c[s[i++]-22]);      /*26-35 is the number range of c[][]..*/
      strcat(x," ");
     }
     else if(s[i]==32)
     {
      strcat(x,"/ ");
      i++;
     }
     else                                        
      i++;         /*i've only managed the alphabets and the numbers....*/
    } 
      return x; 
    }
    
    void toUpperCase(char s[])
    {
        int i=0;
        while(s[i]!='\0')(s[i]>=97 && s[i]<=122)?s[i++]-=32:s[i++];
    }
    It is generally easier to understand if you Say What You Mean (tm). For example, if you mean the letter 'A', use 'A' rather than 65. Also, there are standard functions (found in <ctype.h>) isupper, isdigit, and tolower to make our lives easier. For example, I'd find this easier to understand.
    Code:
    void toUpperCase(char s[])
    {
       int i;
       for ( i = 0; s[i] != '\0'; ++i )
       {
          s[i] = toupper(s[i]);
       }
    }
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  6. #6
    Registered User
    Join Date
    Nov 2005
    Posts
    41
    Quote Originally Posted by Dave_Sinkula
    Code:
    int i=0;  
    while(s[i]!='\0')
    {
     if(s[i]>=65 && s[i]<=90)
     {
      strcat(x,c[s[i++]-65]);
      strcat(x," ");
     }
     else if(s[i]>=48 && s[i]<=57)
     {
      strcat(x,c[s[i++]-22]);      /*26-35 is the number range of c[][]..*/
      strcat(x," ");
     }
     else if(s[i]==32)
     {
      strcat(x,"/ ");
      i++;
     }
     else                                        
      i++;         /*i've only managed the alphabets and the numbers....*/
    } 
      return x; 
    }
    
    void toUpperCase(char s[])
    {
        int i=0;
        while(s[i]!='\0')(s[i]>=97 && s[i]<=122)?s[i++]-=32:s[i++];
    }
    It is generally easier to understand if you Say What You Mean (tm). For example, if you mean the letter 'A', use 'A' rather than 65. Also, there are standard functions (found in <ctype.h>) isupper, isdigit, and tolower to make our lives easier. For example, I'd find this easier to understand.
    Code:
    void toUpperCase(char s[])
    {
       int i;
       for ( i = 0; s[i] != '\0'; ++i )
       {
          s[i] = toupper(s[i]);
       }
    }
    I see. It never occurred to me at the point of time to use char representation. My mind was still thinking about the ascii rep. I will take note of that.

    For the second part, I believe I didnt look through the libraries enough hence im not really aware of the available functions, so i write one instead...

    Thanks. I will take note.

  7. #7
    Registered User
    Join Date
    Nov 2005
    Posts
    41
    Quote Originally Posted by SlyMaelstrom
    Of course. Always free your memory at the end of the program when you dynamically allocate them.
    So i believe it's done like this?
    Code:
    #include <stdlib.h>
    
    int main(void)
    {
    	
    	char *string;
    	int size=10;
    
    	string=malloc(size * sizeof(*string));
        string[1] = 'a';
        printf("Before Free: %c\n",string[1]);
    	free(string);
        printf("After Free: %c",string[1]);
    	return 0;
    }
    Did I use free() correctly?

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Other than the fact that you shouldn't ever try to use something you've freed, yes. You also should be checking to see if malloc failed or not before you try using what you've just allocated.


    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    Nov 2005
    Posts
    41
    Hi, I tried the code below.

    But the array was only declared to take in a size of 10.

    But it seems that when you initialized it, it can go beyond the size of 10.

    I dont get it. Can anyone explain to me please? Thanks

    Code:
    #include <stdlib.h>
    
    int main(void)
    {
    	
    	char *string;
    	int size=10;
            int x=0;
    	string=malloc(size * sizeof(*string));
    
            for(;x<20;x++)string[x]='a';
        
            x=0;
        
           for(;x<20;x++)printf("Before Free: %c\n",string[x]); 
                                                 
    	free(string);
            printf("After Free: %c",string[1]);
    	return 0;
    }

  10. #10
    Registered User
    Join Date
    Mar 2005
    Posts
    140
    whether you declare your array as array[10] or use malloc, there is nothing in the language stopping a programmer from going past the array boundry.

    This is a very bad thing to do.

    you are writing to memory you don't have access to. Who knows what you are writing over. Usually this will lead to a crash.

    Often times with small examples, like the one you've shown, no negative results will be noticed, so you may think it's working fine... It's not!

    As Quazah said you should also not use the variable after you free it, as you are by passing it to printf. Same reasoning, you no longer have access to that memory.
    Last edited by spydoor; 11-21-2005 at 10:51 AM.

  11. #11
    Registered User
    Join Date
    Nov 2005
    Posts
    41
    Quote Originally Posted by spydoor
    whether you declare your array as array[10] or use malloc, there is nothing in the language stopping a programmer from going past the array boundry.

    This is a very bad thing to do.

    you are writing to memory you don't have access to. Who knows what you are writing over. Usually this will lead to a crash.

    Often times with small examples, like the one you've shown, no negative results will be noticed, so you may think it's working fine... It's not!

    As Quazah said you should also not use the variable after you free it, as you are by passing it to printf. Same reasoning, you no longer have access to that memory.
    Oh. Ic. Technically, it's definitely wrong to go beyond the size of 10. But compiler is not stopping us...So it's up to the C programmer to be able to detect such errors...Because i expecting it to crash or generate some weirdo message..lol. Thanks..Now i understand better. Looks like java's run time error: "Array out of bounds" is still on my mind...
    If I'm able to turn back time, I would learn C as my first language.

  12. #12
    Registered User
    Join Date
    Nov 2005
    Posts
    41
    I've rewrote the whole thing. Based on my shallow understanding of dynamic memory alloc and pointers. (hopefully)

    Learning C is not a bed of roses...

    Please help me... Thanks..

    1. I believe there are still some problems with the way I;ve used realloc() .

    2. Apparantly, "char s[]" cannot be a very long sentence! Else when executing the code, it hangs.

    char s[]="morse code"; /*still runs*/
    char s[]="morse code m"; /*still runs*/
    char s[]="morse code mo"; /* The program hangs */

    I dont get it. Why is that so?

    3. Is this correct? I believe not. returning a value signifies the end of function! How do I rectify this?

    Code:
    char *toMorse(char *s)
    {
      ..
      ..
      ..
      ....malloc()....
      .. 
      ..
      ..
      return x; /*Can a function return the value             
                /* first, then free(x)? I*/ 
                /*believe not! */
                /*But I cannot free(x) before I */               
                /*return the value, else the return */
                /*value is empty or null*/
      free(x);
    
    }










    The code:

    Code:
    #include <stdio.h>
    
    void toUpperCase(char *s); 
    char *toMorse(char *s);
    int main(int argc, char *argv[])
    {
    
    char s[]="morse code";
    char *yy=NULL;
    yy=toMorse(s);
    printf("%s ",yy);
    
    return 0;
    }
    
    char *toMorse(char *s)
    {
    char c[][37] = {
            ".-",       /* 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*/
    		};
    
    char *x;
    
    toUpperCase(s);
    
    x=(char *)malloc(10*sizeof(char));
    if(x==NULL)
    {
     printf("Error Allocating Memory");
     exit(1);
    }
    
    while(*s)
    {
     if(*s>=65 && *s<=90)
     {
      x=(char *)realloc(x,5*sizeof(char));
      if(x==NULL)
      {
       printf("Error Allocating Memory");
       exit(1);
      }
      strcat(x,c[*s-65]);
      strcat(x," ");
      s++;
     }
     else if(*s>=48 && *s<=57)
     {
      x=(char *)realloc(x,5*sizeof(char));
      if(x==NULL)
      {
       printf("Error Allocating Memory");
       exit(1);
      }
      strcat(x,c[*s-22]);     
      strcat(x," ");
      s++;
     }
     else if(*s==32)
     {
      x=(char *)realloc(x,3*sizeof(char));
      if(x==NULL)
      {
       printf("Error Allocating Memory");
       exit(1);
      }
      strcat(x,"/ ");
      s++;
     }
     else                                        
      s++;        
    }
    
    return x;
    free(x);
    
    }
    
    void toUpperCase(char *s)
    {
        while(*s)
        {
         if(*s>=97 && *s<=122)
          *s++-=32;
         else
           s++;
        }
    }
    If I'm able to turn back time, I would learn C as my first language.

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    char *toMorse(char *s)
    {
    char c[][37] = {
    This is an array of unknown number of rows, each of them 37 characters in length. Is this what you meant, considering that all of your strings are so small?

    Also, why don't you just use toupper instead of writing your own? If you do plan on writing your own, it's better to use 'A' and 'a' / 'Z' and 'z' for ranges, instead of hard coded numbers, because based on the local, those numbers may not be the same on another machine, or even the same machine, if the local changes.

    To your first bit of code, no, the free is never executed. If you malloc something and need to return it for use, you'll just have to make sure you free when you're all done with it.

    That'll get you started.

    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    Registered User
    Join Date
    Nov 2005
    Posts
    41
    Quote Originally Posted by quzah
    Code:
    char *toMorse(char *s)
    {
    char c[][37] = {
    This is an array of unknown number of rows, each of them 37 characters in length. Is this what you meant, considering that all of your strings are so small?
    Hmm. So that using printf("%s",c[0]) will out put ".-", printf("%s",c[1]) will out put "-..."; in which they are the morse rep of the alphabets....

    37 is because..26 alphabets, plus 10 numbers? [0-9] ..

    Also, why don't you just use toupper instead of writing your own? If you do plan on writing your own, it's better to use 'A' and 'a' / 'Z' and 'z' for ranges, instead of hard coded numbers, because based on the local, those numbers may not be the same on another machine, or even the same machine, if the local changes.
    argh..I'm a bad student!!! I will change this!!

    To your first bit of code, no, the free is never executed. If you malloc something and need to return it for use, you'll just have to make sure you free when you're all done with it.

    That'll get you started.

    Quzah.
    If I free the memory before I return the values, the values returned will be emptied?

    If i do not free the values, the memory dont get released.

    Either way, I've stumpled. Any advise on how to rectify that? Please.

    (nevertheless, it's wrong to have any declarations after a returned value though.. )
    If I'm able to turn back time, I would learn C as my first language.

  15. #15
    Registered User
    Join Date
    Mar 2005
    Posts
    140
    c[rows][cols]

    so you do have 37 (36) rows, but you left that for the compiler to decide by leaving it blank, which is good.

    your cols just needs to be the length of your largest string + 1

    nothing will execute in your function after the return statement.

    You want to free the memory after you're done using it.
    When are you done using it?
    After printf in main.

    after your function call, yy contains the starting address of the memory you allocated.
    Last edited by spydoor; 11-23-2005 at 08:58 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. creating very simple text editor using c
    By if13121 in forum C Programming
    Replies: 9
    Last Post: 10-19-2010, 05:26 PM
  2. Replies: 19
    Last Post: 05-30-2007, 05:47 PM
  3. Problem in simple code.
    By richdb in forum C Programming
    Replies: 6
    Last Post: 03-20-2006, 02:45 AM
  4. Simple C++ question. Error in code somewhere.
    By Paracropolis in forum C++ Programming
    Replies: 10
    Last Post: 02-06-2006, 08:59 AM
  5. how convert english to morse code
    By uler in forum C++ Programming
    Replies: 2
    Last Post: 09-12-2001, 07:56 PM