0

given argument fd in type of FILE* , for example:
FILE* fd = fopen("a.txt","w").

How can I delete all the text that writed in a.txt?

NOTE: I don't know what is the name of the file (I am write a function that gets argument in type of FILE* that someone already opened in the main).


For example:

FILE* fd = fopen("a.txt","w");
assert(fd != NULL); // it's not important for this question.  
fprintf(fd,"hello1\n");
fprintf(fd,"hello2\n");
//.... and now I want to remove all the text from a.txt. How can I do it?
//     The cleaning will be in other function that get just fd (without the 
//     name of the file)
fclose(fd);
Software_t
  • 576
  • 1
  • 4
  • 13

5 Answers5

1

You can open it with the write flag

fopen(filename, "w")

the file would be overwritten with a new empty file if already exists.

Beyondo
  • 2,952
  • 1
  • 17
  • 42
1

You can use ftruncate on most systems except Windows. Windows has the _chsize function. You have to do some preprocessor checks:

#ifdef _WIN32
#include <io.h>
#else
#include <sys/types.h>
#include <unistd.h>
#endif

int truncate_file(FILE *fp);

#ifdef _WIN32
int truncate_file(FILE *fp) {
    return _chsize(_fileno(fp), 0);
}
#else
int truncate_file(FILE *fp) {
    return ftruncate(fileno(fp), 0);
}
#endif

I'm not sure whether this is quite correct on Cygwin or MinGW.

However, if you want to write clean, portable code without a bunch of preprocessor use, your only option is to reopen the file:

FILE *fp;
...
fclose(fp);
fp = fopen(filename, "w");
fclose(fp);
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • `ftruncate` is suported on Windows. Firstly, Microsoft has it in their Visual C run-time library under almost the same interface; they just renamed it to `_chsize`. `ftruncate` is also in Cygwin and therefore [Cygnal](http://www.kylheku.com/cygnal/). – Kaz May 21 '18 at 15:13
  • Visual C: `_chsize(_fileno(fp), 0)`. The size argument is a `long` rather than `off_t`. – Kaz May 21 '18 at 15:16
  • @Kaz: Yes, equivalent functionality is available on Windows. But it's a function with a different name in a different header file. – Dietrich Epp May 21 '18 at 15:22
1

You can use the ftruncate function to truncate an open file. Documentation here:

https://linux.die.net/man/2/truncate

ftruncate(fileno(fd), 0);
little_birdie
  • 5,600
  • 3
  • 23
  • 28
1

Either close and reopen the file (as suggested in Kira Sama's answer), or, on POSIX systems use truncate(2)

However, if you do that, the FILE* handle is out of sync (and you need to at last fflush(3) -bercause FILE* are buffered- before the truncate, and not use the same FILE* without any freopen(3)...). With pure standard C11 (see n1570) there is no way of doing what you want.

In practice, if you use truncate, you should avoid <stdio.h> functions and use read(2) and write(2) directly.

Perhaps higher level libraries like sqlite or gdbm could interest you.

I don't know what is the name of the file (I am write a function that gets argument in type of FILE* that someone already opened in the main).

Then I believe you should not do what you want. (On some POSIX systems, you might use fileno(3) and then ftruncate, but by doing so you are violating some invariants from <stdio.h> and messing up your FILE*)

Look also into rewind(3) & fseek(3)

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

There is no portable way of doing this in C.

In C, the interactions with files are via streams, and no facility exists to remove something from a stream as that makes no real sense. A FILE* is a pointer to an intentionally opaque structure.

I'd be tempted to deal with this at the calling site that sets the FILE* in the first place.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483