1

I'm working in a problem from the "C programming a Modern Approach 2nd Edition" text. I want to write a program that writes the smallest and largest words. The program stops accepting inputs when the user enters a 4-letter word.

I'm using an array of strings to solve this but I can't even get my program to store words in it.

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

#define WORD_LEN 20

int main()
{
    char word[WORD_LEN]={0},ch;
    char *a[10]={};            //Max 10 words in the array
    int i=0,j;

    for(;;)
    {
        printf("Enter a word: ");
        fgets(word,WORD_LEN,stdin);
        strtok(word, "\n");             //removes newline

        a[i] = word;
        if(strlen(word) == 4)          //if word is 4 characters
            break;                     //break out of loop

        i++;
    }

    for(j=0;j<i;j++)                      //displaying array
        printf("%s\n",a[j]);

    return 0;
}

Output:

Enter a word: Analysis
Enter a word: Martin
Enter a word: Jonathan
Enter a word: Dana
Dana
Dana
Dana

Any idea into what I'm doing wrong? Thanks.

1
  • 2
    a[i] = word; : You set same addres of word to a[i] Commented Dec 4, 2016 at 4:41

2 Answers 2

2

As BLUEPIXY mentioned, you are storing same address in all a[i]s. So at the end of the loop, it prints the last output i times.

Solution: You need to allocate memory for a[i] and copy the strings.

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

#define WORD_LEN 20
#define MAX_NUM_WORD 10 //Max 10 words in the array

int main()
{
    char word[WORD_LEN]={0},ch;
    char *a[MAX_NUM_WORD]={0};            
    int i=0,j;

    for(;;)
    {
        printf("Enter a word: ");
        fgets(word,WORD_LEN,stdin);
        strtok(word, "\n");             //removes newline

        a[i] = malloc(sizeof(char)* (strlen(word)+1)); //1 for '\0'

        strcpy(a[i], word);

        i++;
        if(strlen(word) == 4)          //if word is 4 characters
            break;                     //break out of loop

        //i++; //You will be missing last 4 letter word if i++ is here.
        if(MAX_NUM_WORD <= i) //You can store only MAX_NUM_WORD strings
            break;
    }

    for(j=0;j<i;j++)                      //displaying array
        printf("%s\n",a[j]);

   //Your other code.

    for(i=0; i<MAX_NUM_WORD && NULL != a[i]; i++)
        free(a[i]); //Free the allocated memory.

    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

1

Adding to others answers, when using malloc to allocate memory for your strings, it is good to also check the return value of void* pointer returned from it.

Additionally, it is also safe to check the return value of fgets, just to be super safe.

This solution demonstrates these points:

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

#define WORD_LEN 20
#define MAX_NUM_WORD 10
#define EXIT_LEN 4

int 
main(void) {
    char word[WORD_LEN];
    char *a[MAX_NUM_WORD];
    int i = 0, wrd;

    while (i < MAX_NUM_WORD) {
        printf("Enter a word: ");
        if (fgets(word, WORD_LEN, stdin) != NULL) {
            word[strlen(word)-1] = '\0';
        }

        a[i] = malloc(strlen(word)+1);
        if (a[i] == NULL) {
            fprintf(stderr, "%s\n", "Malloc Problem");
            exit(EXIT_FAILURE);
        }

        strcpy(a[i], word);

        i++;

        if (strlen(word) == EXIT_LEN) {
            break;
        }

    }

    // Print and free, all at once. 
    for (wrd = 0; wrd < i; wrd++) {
        printf("%s\n", a[wrd]);
        free(a[wrd]);
        a[wrd] = NULL;
    }

    return 0;
}

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.