Max Maurente
Max Maurente

Reputation: 1

Array of dynamically allocated strings

This program is supposed to dynamically store each string entered into a pointer. Each pointer is part of an array of pointers that will collectively hold all of the strings. When the user enter an empty word, or NULL, it is supposed to quit. My problem is that the code just skips over the NULL conditional statement. I saw some similar posts and have been at it for hours but just can't solve it.

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

void readWord(char wordChar[], int MAX_CHARS);

int main()
{
    int MAX_CHARS = 20;
    int wCount = 0;

    char *wordArray[wCount]; // Array of pointers that will each point to wordChar
    char wordChar[MAX_CHARS];

    int i;
    for(i = 0;;i++)
    {
        wCount++;

        printf("Enter word: ");
        readWord(wordChar, MAX_CHARS); //Reads one word at a time


        //Dynamically store each 
        wordArray[i] = (char*) malloc((int) strlen(wordChar) * (int) sizeof(char));
        wordArray[i] = wordChar;
        printf("%s \n", wordArray[i]); //Troubleshooting *********************

        // If loop ends scanning when word is NULL 
        if(wordArray[i] == 'NULL')
        {   
            printf("if loop");
            break;
        }
        else printf("no loop");
    }

}


/***********************************************************/

void readWord(char wordChar[], int MAX_CHARS)
{
    int letter, i = 0;

    while((letter = getchar()) != '\n')
    {
        if(i < MAX_CHARS)
        {
            wordChar[i] = letter; 
            i++;
        }
    }

    wordChar[i] = '\0';
}

Upvotes: 0

Views: 1206

Answers (2)

BLUEPIXY
BLUEPIXY

Reputation: 40155

#include <stdio.h>
#include <stdlib.h> //for realloc and free (malloc)
#include <string.h>

void readWord(char wordChar[], int MAX_CHARS);

int main(void){
    int MAX_CHARS = 20;
    int wCount = 0;
    char **wordArray = NULL; // Array of pointers that will each point to wordChar
    char wordChar[MAX_CHARS];

    int i;
    for(i = 0;;i++){
        printf("Enter word: ");
        readWord(wordChar, MAX_CHARS); //Reads one word at a time
        if(*wordChar == '\0' || strcmp(wordChar, "NULL") == 0){//empty word or "NULL"
            putchar('\n');
            break;
        }

        wCount++;
        wordArray = realloc(wordArray, wCount * sizeof(*wordArray));//check omitted
        //Dynamically store each
        wordArray[i] = malloc(strlen(wordChar) + 1);//+1 for NUL
        strcpy(wordArray[i], wordChar);//copy string
    }
    //check print and free
    for(i = 0; i < wCount; ++i){
        printf("'%s'\n", wordArray[i]);
        free(wordArray[i]);
    }
    free(wordArray);

    return 0;
}

void readWord(char wordChar[], int MAX_CHARS){
    int letter, i = 0;

    while((letter = getchar()) != '\n' && letter != EOF){
        if(i < MAX_CHARS -1)//-1 for NUL, or char wordChar[MAX_CHARS+1];
            wordChar[i++] = letter; 
        else
            ;//drop letter upto newline
    }
    wordChar[i] = '\0';
}

Upvotes: 0

Laogeodritt
Laogeodritt

Reputation: 760

The short and useless summary is: you're #includeing string.h; use it!


You're trying to compare two pointers directly.

if(wordArray[i] == 'NULL')

This line looks at the pointer value of wordArray[i] to the value of the multi-character literal 'NULL' (note that I didn't say string: you used single quotes here, so 'NULL' has the integer value 0x4e554c4c; see https://stackoverflow.com/a/7459943/510299). If wordArray[i] points to the address 0x12345678, then this is comparing 0x12345678 to 0x4e554c4c and sees that they're not equal.

What you want is to compare strings. In C, you can't do this with == because C strings are char arrays or pointers to chars; == compares the pointer (address) value, as I noted above.

Solution, use strcmp.

if(strcmp(wordArray[i], "NULL") == 0)

(Note the use of double quotes.)

EDIT: Also note that char *wordArray[wCount]; is declared when wCount == 0. This nominally means you tried to declare an array of length 0, which is undefined behaviour. You need to declare wordArray with some length (probably the maximum number of words you can store). [Thanks to riodoro1 for pointing this out in a comment.]


You made a similar blunder with string manipulation in C here:

wordArray[i] = (char*) malloc((int) strlen(wordChar) * (int) sizeof(char));

This line sets the pointer wordArray[i] to some newly allocated memory.

wordArray[i] = wordChar;

This line then proceeds to change the pointer wordArray[i] to point to the original location where the read word was stored. Oops. The next time you go through this loop, wordChar changes, and wordArray[i] is pointing to wordChar... so the new word "replaces" all the previous words.

Solution? You need to copy the string to the memory you just malloc'd. Use strcpy().

printf("if loop");

A conditional (if) statement is not a kind of loop.

Upvotes: 2

Related Questions