0

I'm trying to store data from a file (words line by line) maximum length is 16

when I run the code it only stores the last word on the file and prints it (number of all the words in the file) times.

if the file contains 10 words and the last word is test, the output is test 10 times

when I tried while loop to scan the file I got garbage data

here is my code

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



int main()
{
    FILE *file;

    file = fopen("words.txt", "r");

    char word[20];
    int words_count=0; // count the words in the file

    while (fscanf(file, "%s", word) != EOF)
    {
        words_count++;
    }

    printf("%d", words_count); // i get the right number of words in the file at this step


    char **list_of_words = malloc (words_count * sizeof(char *)); //allocate memory to store enough pointers to charecters

    int length;

    for (int i=0; i<words_count; i++)
        {
            fscanf(file, "%s", word);
            length = strlen(word);
            word[length+1] = '\0';
            list_of_words[i] = malloc (length+1 * sizeof(char)); //allocate memory for each word 
            list_of_words[i] = word;  //I used strcpy(), but I got the same output 
        }



    for (int i=0; i<words_count; i++)
    {
        printf("%s\n", list_of_words[i]); //print the words 
    }


    fclose(file);
}
  • 1
    You read the file to the end when you count words. Every read operation after that fails. – n. m. could be an AI Nov 29 '22 at 12:27
  • 1
    `length+1 * sizeof(char)` Operator precedence/basic math. But just drop `sizeof(char)`, it is pointless. – Lundin Nov 29 '22 at 12:30
  • `list_of_words[i] = word;` is definitely wrong, you need to use `strcpy`. If you don't understand why, you absolutely need to read again the chapter dealing with strings in your learning material. – Jabberwocky Nov 29 '22 at 12:32
  • 1
    "I used strcpy(), but I got the same output" I very much doubt that since that's the bug. Obviously you can't set every `list_of_words` pointer to point at the same local variable `word`. – Lundin Nov 29 '22 at 12:32
  • I reopened the question, the original bug is the missing `fseek` – Jabberwocky Nov 29 '22 at 12:42

1 Answers1

0

There are several issues:

  • once you have read the file you're at the end of the file. If you want to read the file again, you need to move the file pointe rto the start of the file again.
  • you definitely need to use strcpy here, list_of_words[i] = word is pointless, you want to copy the string, not overwrite the previously allocated pointer with a pointer to a local variable (try it and see what happens).
  • length+1 * sizeof(char) is wrong, you intended (length + 1) * sizeof(char). However by chance both expressions give the same result. so this doesn't cause a bug in this particular case. But anyway length+1 is enough because sizeof(char) is 1 by definition.
  • word[lengt+1] = '\0' is useless because after fscanf word[length+1] is 0 by definition. But it doesn't cause a bug.
  ...
  fseek(file, SEEK_SET, 0);               // rewind the file so you can read it 
                                          // again
  for (int i = 0; i < words_count; i++)
  {
    fscanf(file, "%s", word);
    length = strlen(word);
//    word[length + 1] = '\0';            // remove this, it's useless
    list_of_words[i] = malloc(length + 1); // remove the sizeof(char)  which is 1 by definition
    strcpy(list_of_words[i], word);       // use strcpy
  }
  ...
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • thank you so much, that worked perfectly! I didn't know about rewind and fseek function I'm new to programming – Basel Eyad Nov 29 '22 at 12:51