1

I want to save files in c programming and the files names should be like this:

  1. it should be game1.txt if game1.txt doesnt exist.
  2. it should be game2.txt if game1.txt exists.
  3. it should be game3.txt if game2.txt exists.

and so on... so how should I do that????

BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
ali.moh
  • 27
  • 2

2 Answers2

1

If you want to be portable:

  • Use a loop and a counter
  • sprintf() the filename with format-string "game%d.txt"
  • fopen() the file for reading
    • If this succeeds: close it an continue
    • If it fails: exit from the loop and open the file for writing

Note that there is a race condition: If opening for reading failed, another process could create the file before you open it for writing.

There is a GNU-extension for the fopen() mode flags "x", which is for exclusive opening. Using this would eliminate the race condition.

Ctx
  • 18,090
  • 24
  • 36
  • 51
  • The `x` flag is part of the `fopen()` function defined in C11 and also part of the `fopen_s()` function documented in Annex K.3.5 of C11. It might even be available on Windows, therefore, if you use `fopen_s()`. – Jonathan Leffler Jan 25 '17 at 00:01
0

From this question here, What's the best way to check if a file exists in C? (cross platform), the best solution seems to use the access() function found in the unistd.h header.

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

const size_t MAX_FILENAME_LENGTH = 12;
const int MAX_FILENAME_TRIES = 1000;

char *get_next_filename()
{
    char *filename = malloc(MAX_FILENAME_LENGTH);
    FILE *file;
    int found = 0, i = 0;

    do {
        snprintf(filename, "game%d.txt");
        if (access(filename, F_OK) < 0) { //if file does not exist, we've found our name!
            found = 1;
        } else {
            ++i;
        }
    } while (! found && i < MAX_FILENAMES_TRIES);
    return filename;
}

The code here returns the next available filename as a C string, starting from game0.txt up to gameN.txt, where N is the value of MAX_FILENAME_TRIES. Don't forget to free() the file name once you've used it.

Community
  • 1
  • 1
Adrien
  • 273
  • 2
  • 8
  • If you're going to use POSIX `access()`, it's worth avoiding the race condition with POSIX `open()` and `O_EXCL | O_CREAT` amongst the flags, so it creates the file if it doesn't exist but fails if it does without the TOCTOU (time of check, time of use) vulnerability. You can use `fdopen()` to convert the file descriptor (`int`) into a file stream (`FILE *`). This is like `mkstemp()` — it creates the file and returns the file descriptor. It might be better to have the space for the name passed into the function rather than forcing the use of `malloc()` and `free()`; no leak from your code. – Jonathan Leffler Jan 25 '17 at 00:05