3

Hello fellow programmers. I have little problem. I cannot figure out how to open files with different numbers (in the filename) going from 1 to whatever number of files exist.

For example, I have two (or eventually n) files named game_1.txt and game_2.txt. This loop should open these two files (or eventually all with this pattern, in that folder).

I am getting errors, namely:

passing argument 2 of 'fopen' makes pointer from integer without a cast.

Here is what I have:

main()
{
    FILE *fr;
    int i=1;
    char b;

    while(fr=fopen("game_%d.txt",i) != NULL)
    {
        while(fscanf(fr,"%c",&b) > 0)
        {
            printf("%c",b);
        }
        i++;
    }


    return 0;
}
MarredCheese
  • 17,541
  • 8
  • 92
  • 91
  • you should try to read the man of fopen, the second argument is not for the file numbering (whatever it means) see https://www.systutorials.com/docs/linux/man/3-fopen/ for example – OznOg Nov 25 '18 at 19:39
  • Sorry, cannot get what do you mean, please explain to fellow starting programmer in simplier words. Many thanks – Dušo Morháč Nov 25 '18 at 19:40
  • the second parameter iis for the mode, I guess it should be "r" in your case, see https://stackoverflow.com/questions/41407318/warning-passing-argument-2-of-fopen-makes-pointer-from-integer-without-a-cast for another example – OznOg Nov 25 '18 at 19:43
  • Okay, but how else do I make it to open files with %d as variable such as game_1.txt & game_2.txt and else.. – Dušo Morháč Nov 25 '18 at 19:48
  • Do not use nor recommend `sprintf`. use `snprintf`. – jamesdlin Nov 25 '18 at 20:08

2 Answers2

3

Use sprintf() to build the filename:

#include <stdio.h>
                // the c standard requires, that main() returns int
int main(void)  // you should put void in the parameter list if a
{               // when a function takes no parameters.
    char filename_format[] = "game_%d.txt";
    char filename[sizeof(filename_format) + 3];  // for up to 4 digit numbers

    for (int i = 1; i < 1000; ++i) {
        snprintf(filename, sizeof(filename), filename_format, i);
        FILE *fr = fopen(filename, "r");  // open for reading

        if(!fr)      // if the file couldn't be opened
             break;  // break the loop

        int ch;
        while ((ch = fgetc(fr)) != EOF)
            putchar(ch);

        fclose(fr);  // close the file when no longer needed.
    }                // since fr will be overwritten in the next
                     // iteration, this is our last chance.
    return 0;
}
Swordfish
  • 12,971
  • 3
  • 21
  • 43
-1

You may need something like this:

#include <stdio.h>

int main()
{
    FILE *fr;
    int i = 1;
    char b;

    while (1) // infinite loop, until broken out of
    {
        char to_open[32];
        snprintf(to_open, 32, "game_%d.txt", i);

        if ((fr = fopen(to_open, "r")) == NULL)
        {
            break;
        }

        while (fscanf(fr, "%c", &b) > 0)
        {
            printf("%c",b);
        }

        fclose(fr); // close the file after work is done

        i++;
    }

    return 0;
}

In the original code, the API call to fopen would fail, because the second argument it requires is a string, containing the modes that should be used when opening a file (in this case I chose "r" - Open file for input operations).

The call to snprintf into an intermediate temporary array is required, because fopen does not support string formatting (such as using %d).

Afterwards, the main loop can be finished, when the next file cannot be opened anymore using the break statement.

It is also a good idea to include a call to fclose after the necessary work is done (in this case, the "work" would be the inner while loop), so that there are no unnecessary memory and resource leaks.

Kirko
  • 64
  • 4
  • What year is this? Why does everyone keep recommending `sprintf`? Use `snprintf`. It was standardized almost 20 years ago. – jamesdlin Nov 25 '18 at 20:10