2

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

4
  • Don't cast return of malloc Commented Oct 10, 2016 at 13:19
  • 1
    You should use fgets to store the whole sentence and then compute it. Commented Oct 10, 2016 at 13:20
  • To find where your code goes wrong, use a debugger. It's a really useful tools to find but but also to learn (which is your main goal here). Commented Oct 10, 2016 at 13:23
  • 1
    probably this solve: words[word_count++] = word; --> strcpy(words[word_count++], word); Commented Oct 10, 2016 at 13:26

1 Answer 1

1

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))
Sign up to request clarification or add additional context in comments.

4 Comments

@You're welcome. I updated my answer with another issue.
You have the word counter, word_count. So when it exceed the required number you can skip all other chars until \n
If you are talking about a different implementation then the posted one with realloc, and using an array of pointers, you can simply check sizeof(array)/sizeof(array[0]) to retrieve the number of element. So you can check that your word counter is <.
Too much ;) 20 years more or less.

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.