tadm123
tadm123

Reputation: 8787

C storing strings into an array

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.

Upvotes: 1

Views: 77

Answers (2)

RoadRunner
RoadRunner

Reputation: 26315

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;
}

Upvotes: 1

MayurK
MayurK

Reputation: 1947

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;
}

Upvotes: 2

Related Questions