0

I am trying to write a C program which takes input from a .txt file, stores the words in an array of char pointers, averages the word length and prints out any words which exceed the average length. Right now I am trying to get a print function working (print_array), I want to do this recursively. For some reason the print function is not printing out all elements of the array, it is only printing the first element and removing the first character each time. What am I doing wrong here? Cheers

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ARRAYLEN 100
#define CHARLEN 79

void *emalloc(size_t s) {
    void *result = malloc(s);
    if (NULL == result) {
        fprintf(stderr, "Memory allocation failed!\n");
        exit(EXIT_FAILURE);
    }
    return result;
}

void print_array(char *a, int n) {
    if (n > 0) {
        printf("%s\n", &a[0]);
        print_array(a + 1, n - 1);
    }
}


int main(void) {
    char word[CHARLEN];
    char *wordlist[ARRAYLEN];
    double average;
    int num_words;

    num_words = 0;
    average = 0.0;
    while (num_words < ARRAYLEN && 1 == scanf("%79s", word)) {
        wordlist[num_words] = emalloc((strlen(word) + 1) * sizeof wordlist[0][0]);
        strcpy(wordlist[num_words], word);
        average += strlen(word);
        num_words++;    
    }

    average = average / num_words;

    printf("Average is %.2f\n", average);

    print_array(*wordlist, num_words);


    return EXIT_SUCCESS;
}

Output -

Average is 9.71
hello
ello
llo
lo
o
2
  • 2
    char word[CHARLEN]; is 1 too small for "%79s". Commented Sep 15, 2017 at 1:39
  • Also if you are using a macro CHARLEN, it would be better to use "%" #CHARLEN "%s". Commented Sep 15, 2017 at 2:51

2 Answers 2

2

The argument *wordlist is the pointer to first element of *wordlist[], but you want to print a two-dimensional array! So the code must look like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void print_char_array(char *words[], int len) {
    if (len > 0) {
        printf("%s\n", words[0]);
        print_char_array(words + 1, len - 1);
    }
}

int main (int args, char *argv[]) {
    char *words[] = {
        "hello", "print", "array", "recursively", "output"
    };
    print_char_array(words, 5);
    return 0;
}

My English is poor, hope the code can help you!

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

Comments

1
char *wordlist[ARRAYLEN];

Here we have an array of C strings.

print_array(*wordlist, num_words);

Here we deference the pointer, getting the first C string in the array and passing that to print_array.

void print_array(char *a, int n) {
    if (n > 0) {
        printf("%s\n", &a[0]);
        print_array(a + 1, n - 1);
    }
}

Here we take one C string, and if n isn't zero, print it (&a[0] is a pointer to the first element in the array, which will end up being the same as a itself). Then we add one to the C string pointer, so that we do the same thing starting from the second character. And so on.

SOLUTION: If you want to print an array of C strings, have the print_array function take the whole array, not just an individual string—i.e. have it take char ** rather than char *. Then, get rid of the & in print_array and the * in the line that calls print_array.

EDIT: as pointed out by @chux, your CHARLEN is also too small. Make it 80 so that your strings have room for 79 characters plus the necessary null terminator.

Comments

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.