1

The main idea of the program is to code text into morse and decode morse into text.

But the program is broke, i don't know why the program doesn't work when i write the space between two words, and i have this problem with the code and decode.

void encode_out(const char *s){
    for(;;++s){
        char ch = *s;
        if(ch == '\0')
            break;
        if(isalpha(ch)){
            ch = toupper(ch);
            fputs(table[ALPHA][ch - 'A'], stdout);//`-'A'` depend on the sequence of character code
        } else if(isdigit(ch))
            fputs(table[NUM][ch - '0'], stdout);
        else if(ch == ' ')
            fputc('/', stdout);//need rest space skip ?
        else 
            ;//invalid character => ignore
        fputc(' ', stdout);
    }
    fputc('\n', stdout);
}

static void decode_out_aux(MTree *tree, const char *s){
    if(tree == NULL) return;
    if(*s == '\0')
        fputc(tree->value, stdout);
    else if(*s == '/')
        fputc(' ', stdout);
    else if(*s == '.')
        decode_out_aux(tree->dot, ++s);
    else if(*s == '-')
        decode_out_aux(tree->bar, ++s);
}

void decode_out(const char *s){
    char *p;
    while(*s){
        p = strchr(s, ' ');
        if(p){
            if(p-s != 0){
                char code[p-s+1];
                memcpy(code, s, p-s);
                code[p-s]='\0';
                decode_out_aux(root, code);
            }
            s = p + 1;
        } else {
            decode_out_aux(root, s);
            break;
        }
    }
    fputc('\n', stdout);
}

static void insert_aux(MTree **tree, char ch, const char *s){
    if(*tree == NULL)
        *tree = calloc(1, sizeof(**tree));
    if(*s == '\0')
        (*tree)->value = ch;
    else if(*s == '.')
        insert_aux(&(*tree)->dot, ch, ++s);
    else if(*s == '-')
        insert_aux(&(*tree)->bar, ch, ++s);
}

static inline void insert(char ch, const char *s){
    if(*s == '.')
        insert_aux(&root->dot, ch, ++s);
    else if(*s == '-')
        insert_aux(&root->bar, ch, ++s);
}

void make_tree(void){
    root = calloc(1, sizeof(*root));
    //root->value = '/';//anything
    int i;
    for(i = 0; i < 26; ++i)
        insert('A'+i, table[ALPHA][i]);
    for(i = 0; i < 10; ++i)
        insert('0'+i, table[NUM][i]);
}

static void drop_tree_aux(MTree *root){
    if(root){
        drop_tree_aux(root->dot);
        drop_tree_aux(root->bar);
        free(root);
    }
}

void drop_tree(void){
    drop_tree_aux(root);
}
  • I think you've met most of the friends from ``. Now it's time to meet `isblank()`. Note that when you hit enter, you're adding at least a `\n` (new line character) to your input string. – Janez Kuhar Oct 30 '16 at 04:46
  • Possible duplicate of [How do you allow spaces to be entered using scanf?](http://stackoverflow.com/questions/1247989/how-do-you-allow-spaces-to-be-entered-using-scanf) – GoodDeeds Oct 30 '16 at 05:25
  • You seem to be passing `char **` to functions expecting `char *`. The compiler should be complaining. Ditto for `scanf()`. And you haven't allocated memory for the pointers to point at. That's a lot of problems to be fixed. – Jonathan Leffler Oct 30 '16 at 06:35

2 Answers2

1

There are probably some other issues, but at least you need to fix this:

void encode_out(const char *s)

In this function, s is an input parameter and it looks certain that you are modifying its content, therefore s cannot have const modifier. Change that to:

void encode_out(char *s)

Look for other functions in your program that have similar problems, such as decode_out

artm
  • 17,291
  • 6
  • 38
  • 54
1
char *text;
char *morse;
...
scanf("%s", &text);
encode_out(&text);
printf("Enter the morse code: ");
scanf("%s", &morse);
decode_out(&morse);

text and morse are pointers, do not add reference operator.

text is uninitialized pointer, it cannot be used in scanf. The usage is as follows:

char text[100];
scanf("%s", text);

For the rest of the code, it is unlikely to work and over complicated. Use a translate function to compare each morse code.

char translate(const char* buf)
{
    for (int i = 0; i < 26; i++)
        if (strcmp(buf, alpha[i]) == 0)
            return 'A' + (char)i;
    if (strcmp(buf, "/") == 0)
        return ' ';
    for (int i = 0; i < 10; i++)
        if (strcmp(buf, num[i]) == 0)
            return '0' + (char)i;

    //to indicate an error:
    return '?';
}

Use strtok to break the morse code in to parts, translate each part and add to output:

char *decode(const char* src)
{
    char *code = malloc(strlen(src) + 1);
    char *dst = malloc(strlen(src) + 1);
    strcpy(code, src);
    int dst_len = 0;
    char *token = strtok(code, " ");
    while (token)
    {
        dst[dst_len++] = translate(token);
        token = strtok(NULL, " ");
    }

    free(code);
    dst[dst_len] = 0;
    return dst;
}

int main(void)
{
    char *dst = decode(".... . .-.. .-.. --- / .-- --- .-. .-.. -..");
    printf("%s\n", dst);
    free(dst);
    return 0;
}

output: "HELLO WORLD"

Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • You can allocate with `scanf`, take a look at `man scanf` and look for the `m` modifier (on Linux) to `%s, %c, %[` (older Linux and windows uses `a` as the modifier). Note you need to provide a *pointer to pointer to char*. – David C. Rankin Oct 30 '16 at 08:31
  • @DavidC.Rankin I didn't know that. I am just going to cross out that comment for now. – Barmak Shemirani Oct 30 '16 at 08:41
  • 1
    Sure, it was kind of a neat trick when I found it, but it still comes with all the required (or generally missing) discipline `scanf` demands to properly account of all `eol` and `EOF` conditions new users generally stumble over. – David C. Rankin Oct 30 '16 at 10:59