RoadRunner
RoadRunner

Reputation: 26315

Array of Strings issue

I am currently having difficulty reading words separated by spaces line by line from stdin. I am trying to read words line by line, and just print them, from accessing an array of strings.

If I am trying to read this sentence:

Enter words: Hi there, how was your day sir?

Then I just want to print the sentence underneath, like this:

Your sentence: Hi there, how was your day sir?

This is what my code is so far:

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

int
main(int argc, char *argv[]) {
    char *word = NULL;
    char **words = NULL;
    int word_size = 1, word_len = 0, word_count = 0;
    int words_size = 1, i, ch;

    word = (char*)malloc(word_size *sizeof(char));

    words = (char **) malloc(words_size*sizeof(char*));

    printf("Enter words:\n");
    while ((ch = getchar()) != EOF) {
        if (isalpha(ch)) {
            word_size++;
            word = realloc(word, word_size+1);
            word[word_len++] = ch;
            word[word_len] = '\0';
        }

        if (isspace(ch)) {
            words_size++;
            words = realloc(words, words_size+1);

            words[word_count] = malloc(strlen(word)+1);

            words[word_count++] = word;
            word_len = 0;
            word_size = 1;
        }

        if (ch == '\n') {

            printf("Your sentence is:\n");
            for (i = 0; i < word_count; i++) {
                printf("%s ", words[i]);
            }
            printf("\n");

            word_len = 0;
            word_size = 1;
            words_size = 1;
        }

    }
    return 0;
}

I am just not sure why this doesn't work, and why it prints the last word. I know there is a lot of mallocing and reallocing, I am just trying to get better at using them.

Any help would be appreciated

Upvotes: 2

Views: 104

Answers (1)

LPs
LPs

Reputation: 16213

You are failing assigning the word to your char **.

Using

words[word_count++] = word;

You are assigning address of local variable word to pointer words[word_count] That gave you, at the end of computation, all words with last stored word into word c-string.

You prepare space for the word c-string using

words[word_count] = malloc(strlen(word)+1);

So what you have to do is to copy the content of word c-string into allocaded space

strcpy(words[word_count++], word);

Otherwise you are leaking memory allocated for the word.

Side notes:

  1. malloc and realloc can fail, so check its return value != NULL
  2. You must free mallocated memory. On "hi-level" OS memory is freed automatically at the end of execution, but is not granted on all platforms/OS

EDIT

Another problem is that you are reallocating the wrong size for your char** You shoud use

words_size++;
words = realloc(words, sizeof(*words)*words_size);

That is size of char * for the new number of words to store

You can also avoid to use strlen, you have the length of word stored into word_len variable

words[word_count] = malloc(word_len+1);

Last thing, before to store a new word you should check that at least alpha char was found. This avoid the output of first space char of your test sting:

if ((isspace(ch)) && (word_size>1))

Upvotes: 1

Related Questions