0

I have been working some time on the code below but for some reason there is no way I can print out correctly the chars array of an array after returning it and using it in the main function. I cannot come up with any other things I could print in the code to check what is wrong. I do have checked other similar posts in the forum but I cannot spot any differences between the answers given there and how my code is written. Does anyone spot anything wrong?

Many thanks in advance.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STRING 35

char **getWordsList(size_t *wordsNumber);

int main(){
    int wordsNumber;
    char **arrayOfArrays=getWordsList(&wordsNumber);
    printf("WordsNumber is %d",wordsNumber);
    printf("\nPrinting the resulting array of arrays: \n");
    
    for (size_t indx=0; indx<wordsNumber; indx++){
        printf("%s ", *(arrayOfArrays+indx)); //WHY ISNT THE STRING PRINTED CORRECTLY ?
    
        }
    free(*arrayOfArrays);
    free(arrayOfArrays);
    return 0;
}

char **getWordsList(size_t *wordsNumber){
    printf("Please enter the number of words: ");
    scanf("%zu",wordsNumber);
    fflush(stdin);
    char **wordsList=malloc(sizeof (char *)*(*wordsNumber));
    
    if (wordsList!=NULL){
    for (size_t indx=0; indx<*wordsNumber; indx++)
        {
            char inputWord [30];
            printf("Please enter a word: ");
            fgets(inputWord,sizeof(inputWord),stdin);
            fflush(stdin);
            printf("Word is %s",inputWord);
            
            *(wordsList+indx)=malloc(MAX_STRING*sizeof(char));
            if (*(wordsList+indx)){
                *(wordsList+indx)=inputWord;
                printf("Added array component is: %s\n",*(wordsList+indx));
                }
        }
        
    return wordsList;}
    
    else{
        printf("Error in allocating memory for array of arrays");
        }
    }
Oriol
  • 75
  • 5
  • What **is** it printing? What do you want it to print instead? – Shawn Dec 25 '21 at 18:34
  • @Oriol This statement *(wordsList+indx)=inputWord; produces a memory leak and after exiting the function also undefined behavior.:) – Vlad from Moscow Dec 25 '21 at 18:35
  • @Shawn. I want to print each of the char arrays of the array with this: printf("%s ", *(arrayOfArrays+indx)); – Oriol Dec 25 '21 at 18:36
  • `*(wordsList+indx)`... Most people would use `wordsList[indx]`. And `fflush(stdin)` is undefined. – Shawn Dec 25 '21 at 18:37
  • @VladfromMoscow. Then using strcpy instead would solve the issue? – Oriol Dec 25 '21 at 18:38
  • @Oriol Yes, you need to use strcpy. – Vlad from Moscow Dec 25 '21 at 18:39
  • @Oriol And instead of this statement free(*arrayOfArrays); you need to free all allocated arrays. – Vlad from Moscow Dec 25 '21 at 18:41
  • Aside: don't forget to remove the newline (if any) that `fgets` puts in the input string. Please see [Removing trailing newline character from fgets() input](https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input/28462221#28462221) – Weather Vane Dec 25 '21 at 18:41
  • @Shawn. It is my understanding I need fflush(stdin) at least once in the code after scanf because otherwise the input cannot be entered – Oriol Dec 25 '21 at 18:42
  • The reason you think you need `fflush(stdin)` is because you have `scanf()` followed by `fgets()`. Please see [fgets() doesn't work after scanf](https://stackoverflow.com/questions/5918079/fgets-doesnt-work-after-scanf). It causes problems when you mix your input methods. Better to use `fgets()` followed by `strtol()` to obtain the number of words. One reason why you shouldn't use `fflush(stdin)` is because it would make it impossible to redirect input from a file. – Weather Vane Dec 25 '21 at 18:45
  • @WeatherVane. Yes, you are right. Completely forgot about removing the newlines from the chars array – Oriol Dec 25 '21 at 18:51
  • You never need `fflush(stdin)`. – n. m. could be an AI Dec 25 '21 at 21:58
  • Thank you all for your help. I have written an answer which shows a working code after factoring in all your pieces of advice. – Oriol Dec 26 '21 at 17:58

1 Answers1

0

Thanks to the help I got from the post comments, I was able to produce a working code. I am posting it so others who are struggling wih similar problems can benefit from it.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STRING 35

char **getWordsList(size_t *wordsNumber);

int main(){
    int wordsNumber;
    
    char **answer=getWordsList(&wordsNumber);
    printf("WordsNumber is %d",wordsNumber);
    printf("\nChecking: \n");
    
    for (size_t indx=0; indx<wordsNumber; indx++){
        printf("%s ", answer[indx]);
        free(answer[indx]);
        }
    free(answer);   
    return 0;
}

char **getWordsList(size_t *wordsNumber){
    long wordsNumberFoo;
    char wordsNumberStr [40];
    char *wordsNumberPtr;
    
    printf("Please enter the number of words: ");
    fgets(wordsNumberStr, sizeof(wordsNumberStr), stdin);
    wordsNumberFoo=strtol(wordsNumberStr, &wordsNumberPtr, 10);
    *wordsNumber=(size_t)wordsNumberFoo;
    
    char **wordsList=malloc(sizeof (char *)*(*wordsNumber));
    
    if (wordsList!=NULL){
    for (size_t indx=0; indx<*wordsNumber; indx++)
        {
            char inputWord [30];
            printf("Please enter a word: ");
            fgets(inputWord,sizeof(inputWord),stdin);
            inputWord[strcspn(inputWord, "\n")] = 0;
            printf("Word is %s\n",inputWord);
            
            strncpy(*(wordsList+indx),inputWord, MAX_STRING);
            printf("Added array component is: %s\n",*(wordsList+indx));
        }
        
    return wordsList;}
    
    else{
        printf("Error in allocating memory");
        return NULL;

        }
    }
    

Oriol
  • 75
  • 5