2

I'm trying to open a file called dictonary.txt and copy its contents to a string array. But I forget how to do it.

Here's what I have so far:

int main(int argc, char** argv) 
{
    char dict[999][15];
    FILE *fp;
    fp = fopen("dictionary.txt", "r");
    while(feof (fp))
    {
            
    }
}

Can someone help me with this?

EDIT: There are 999 words in the file and all of them have 15 characters or less.

Kazumi411
  • 37
  • 4
  • 1
    [`while (!feof(file))` is always wrong](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong?r=SearchResults&s=1|404.0572) and `while (feof(file))` doesn't make sense – pmg Mar 27 '21 at 17:08
  • It will depend on the structure of the input file, but [`fgets()`](https://man7.org/linux/man-pages/man3/fgets.3.html) and [`fscanf()` or `sscanf()`](https://man7.org/linux/man-pages/man3/fscanf.3.html) will be useful. – MikeCAT Mar 27 '21 at 17:08
  • 1
    @pmg It is actually `while(feof (fp))` here. No `!` and it is worse. – MikeCAT Mar 27 '21 at 17:08
  • 1
    do you want up to 999 words shorter than 15 chars each... or up to 15 words shorter than 999 chars each (as your code suggests)? – pmg Mar 27 '21 at 17:11
  • Also you should check if the result if `fopen()` is not `NULL` before doing further works. – MikeCAT Mar 27 '21 at 17:12
  • " i forget how to do it." - lickily you don't have to remember that stuff - there are references: http://www.cplusplus.com/reference/cstdio/ You might at least include a fragment of the file content. It is line, space or comma delimited for example. – Clifford Mar 27 '21 at 17:48
  • @Kazumi411 I did change the file name, IDK if you missed it, corrected it now. – anastaciu Mar 27 '21 at 18:31
  • @anastaciu I did tried that, still didn't work. i made sure the txt file is in the project file so what could be wrong? – Kazumi411 Mar 27 '21 at 18:42
  • 1
    @Kazumi411 it should work flawlessly, I added some more code to help you pinpoint the problem, I also added a live sample, check it https://wandbox.org/permlink/TDDyZXswA07imf9a – anastaciu Mar 27 '21 at 18:50

2 Answers2

3

As stated in the comments while(!feof (fp)) will not work as intended, you are also missing the negator but that's beside the point, a simple way to do this is to use fgets and take advantage of its return value to detect the end of the file, as it returns NULL when there are no more lines to read:

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

int main()
{
    char dict[999][15];
    size_t ind; // store the index of last read line

    FILE *fp = fopen("dictionary.txt", "r");

    if (fp != NULL) // check if the file was succefully opened
    {
        // read each line until he end, or the array bound is reached
        for (ind = 0; fgets(dict[ind], sizeof dict[0], fp) && ind < sizeof dict / sizeof dict[0]; ind++)
        {
            dict[ind][strcspn(dict[ind], "\n")] = '\0'; // remove newline from the buffer, optional
        }

        for (size_t i = 0; i < ind; i++) // test print
        {
            puts(dict[i]);
        }
    }
    else
    {
        perror("Error opening file");
    }
}

Note that this will also read empty lines, i.e. lines with \n only or other blank characters.

Test sample

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • Also be careful: `fgets()` will put the newline character read to the buffer, so you may want to remove that before further processing. – MikeCAT Mar 27 '21 at 17:35
  • @MikeCAT added an option to remove it, also a note that *blank* lines will also be parsed. – anastaciu Mar 27 '21 at 17:40
  • I just posted a function to have fgets without the new line if you want to avoid parsing your string twice: https://codereview.stackexchange.com/questions/258772/fgets-without-the-line-return your insights are welcome! @MikeCAT and anastaciu – Antonin GAVREL Mar 27 '21 at 17:42
  • 1
    note the edit in the question correcting the array dimension order. – Clifford Mar 27 '21 at 17:50
0
#include <stdio.h>

int main()
{
    char dict[999][15];
    FILE * fp;
    fp = fopen("dictionary.txt", "r");

    int i = 0;
    while (fscanf(fp, "%s", dict[i]) != EOF)
            i++;

    // i is your length of the list now so you can print all words with
    int j;
    for (j = 0; j < i; j++)
            printf("%s ", dict[j]);

    fclose(fp);
    return 0;
}

Instead of != EOF, you can also do == 1 because fscanf returns a value of scanned things. So if you do:

fscanf(fp, "%s", dict[i]);

it will return 1 if a word is successfully scanned. And it won't when it reaches the end of the file. So you can do it that way too.