0

I have a struct with letters inside and I want to give the letters to an array so i can use it afterwards. It works if i would just print the letters.

Top (struct):

 #include "stdafx.h"

typedef struct { char* code; char* letter;}morse_tabelle; 

morse_tabelle tabelle[] = {
    { ".-", "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" },
    { "/", " " },
    };

For the arraysize:

#define ARR_SIZE(x) (sizeof(x)/sizeof((x)[0]))

Function:

    void morse_to_text(void)
    {


    char input[100];
    char* morse_letter;

    int j = 0;
    char* translation[50];


    printf_s("\n\nput in Morsecode:\n\n");
    fgets(input, 100, stdin);                                             
    input[strlen(input)-1] = '\0';                                       

    morse_letter = strtok(input, " ");                               

    while (morse_letter)                                                      
    {
        for (int i = 0; i < ARR_SIZE(tabelle); i++)                            
        {

            if (!strcmp(morse_letter, tabelle[i].code))                  
            {
                translation[j] = tabelle[i].letter;                    
                j++;
                /*printf_s("%s", tabelle[i].letter);*/   //This works              
            }
        }
        morse_letter = strtok(NULL, " ");                            
    }

    /*output*/
    printf_s("\n\n---------------\n\n");
    for (int i = 0; i <= strlen(translation[50]); i++){
            printf("%s", translation[i]);
    }

};

It sort of works if i change the char* letter to char letter inside of the struct. but then i get a buffer overrun. The question again: how can i store strings inside an array.

8
  • 2
    Your code looks like pure C to me. What the C++ tag? Commented May 3, 2017 at 8:38
  • 1
    What's strlen(translation[50])? Commented May 3, 2017 at 8:45
  • 2
    for (int i = 0; i <= strlen(translation[50]); i++) -> for (int i = 0; i < j; i++) Commented May 3, 2017 at 8:50
  • 1
    use break after j++ in for loop for efficiency Commented May 3, 2017 at 8:55
  • 1
    Your morse code for "C" has surplus spaces at each end. Commented May 3, 2017 at 8:57

3 Answers 3

3

What you actually want is this:

char translation[50]; // no string array, char array!

Then have the letter as char as you intended:

typedef struct { char* code; char letter;} morse_tabelle;

With that, you now can simply do

translation[j] = tabelle[i].letter;

again, just as before. Only the data type changed...

However, you need to null-terminate your translated string, else you cannot use it with printf("%s", translation)

while(...) { ... }
translation[j] = 0;

// output:
// no for loop any more!

printf("%s", translation);

An alternative to terminating the null character would be giving the length to the printf format parameter:

while(...) { ... }
// no termination any more...

// output:
// no for loop any more!

printf("%.*s", j, translation);

See printf for details (OK, link actually is C++, but documentation is exactly true for C, too...).

Sign up to request clarification or add additional context in comments.

2 Comments

Same answer as mine but slightly better laid out and includes detail of null termination which I missed since I took it for granted.
i tried it similar before, the biggest problem was that i didnt terminate the translation-array with a 0, so i got a bufferoverload i guess. now with this it works well
1

Instead of:

translation[j] = tabelle[i].letter;

do:

translation[j] = tabelle[i].letter[0];

Or instead, and even better, do:

typedef struct { char* code; char letter;} morse_tabelle; 

morse_tabelle tabelle[] = {
    { ".-", 'A' },
    { "-...", 'B' },
    { " -.-. ", 'C' },
    { "-..", 'D' },
    etc. etc.

char translation[50];
...
printf("%s\n", translation);

Or, if you want to print out the translation letter by letter:

for (int i = 0; i < strlen(translation); i++)
{
    printf("%c\n", translation[i]);
}

To add some basic C tuition:

char * is a pointer to an array of char types. "A" is a char array with two elements and can be written as { 'A', '\0' }. Hence assigning "A" to a char type is wrong.

If you define letter as a char * and populate the data with a one character string, then you can access the character by indexing the 0th element as letter[0]. However, rather than using character arrays all over the space and wasting memory and over-complicating your code, it is better just to use characters instead.

4 Comments

This answer is not quite correct. Rethink it please.
It would be nice if you would point out exactly which part of this answer is not correct. In truth the original code is so full of bugs that it needs a complete rewrite for a fully correct answer and I don't have time for that.
You write Instead of: translation[j] = tabelle[i].letter; do: translation[j] = tabelle[i].letter[0];, but this implies that you need also modify what you have described under Or, even better do:.
@Michael Walz, thanks. It was correct, just a question of unclear text. There was an implicit "instead" in the second option that I have now made explicit.
0

Here:

for (int i = 0; i <= strlen(translation[50]); i++) {

strlen(translation[50] is wrong. translation is an array of 50 pointers to char*. So strlen(translation[50]) is the length of the 50th translated character (which BTW only exists if you have typed in 50 morse codes) and not the number of elements you've put into the translation array. You've put j char* pointers into the translation array, therefore the correct code is:

for (int i = 0; i < j); i++) {

3 Comments

translation[50] actually asks for the 51th element
@n.caillou yes if you start at 1.
this was a good example for me to understand pointers a bit more, thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.