I'm using C to write some data to a file. I want to erase the previous text written in the file in case it was longer than what I'm writing now. I want to decrease the size of file or truncate until the end. How can I do this?
6 Answers
If you want to preserve the previous contents of the file up to some length (a length bigger than zero, which other answers provide), then POSIX provides the truncate()
and ftruncate()
functions for the job.
#include <unistd.h>
int ftruncate(int fildes, off_t length);
int truncate(const char *path, off_t length);
The name indicates the primary purpose - shortening a file. But if the specified length is longer than the previous length, the file grows (zero padding) to the new size. Note that ftruncate()
works on a file descriptor, not a FILE *
; you could use:
if (ftruncate(fileno(fp), new_length) != 0) ...error handling...
However, you should be aware that mixing file stream (FILE *
) and file descriptor (int
) access to a single file is apt to lead to confusion — see the comments for some of the issues. This should be a last resort.
It is likely, though, that for your purposes, truncate on open is all you need, and for that, the options given by others will be sufficient.
For Windows, there is a function SetEndOfFile()
and a related function SetFileValidData()
function that can do a similar job, but using a different interface. Basically, you seek to where you want to set the end of file and then call the function.
There's also a function _chsize()
as documented in the answer by sofr.

- 730,956
- 141
- 904
- 1,278
-
Remarkably similar, Lance! At least one of us probably got the info correct. (Using
is not supposed to be necessary in the more recent POSIX standards; for safety, it does no harm, though.) – Jonathan Leffler May 17 '09 at 03:29 -
1Is there such function in c++ vs 2003 I couldn't find it? non of the includes helped maybe I missed something? I do not want to open the file with w but use the file opended already – sofr May 17 '09 at 05:43
-
I'm not sure. Most of the POSIX functions are available in MSVC, but Microsoft decided that it needed to put an underscore at the start of the function name -- hence _truncate() and _ftruncate(). Also, these are C functions, not C++; you may need to track it down that way. In the MSVC 2008 I have, I don't find a unistd.h header; I'm not sure whether that is available in other editions, or whether I've simply not looked in the right place. – Jonathan Leffler May 17 '09 at 14:48
-
I'm pretty sure (at least on the Mac) that it is not safe to call `ftruncate(file no(fp))` on an open file. Neither the internal read nor write buffers of `fp` will be flushed. Call `std::fflush` before to flush the write buffers and `std::freopen` afterwards to reinitialise `fp` – Sebastian Oct 28 '15 at 14:44
-
1@Sebastian: there is no `std::fflush` or `std::freopen` in C; you must be confusing this with a different language — presumably C++. It depends on what you mean by 'is not safe'. Certainly, you're immediately stepping outside the knowledge of the file stream, doing operations behind its back. Nothing is going to flush buffers; you should use `fflush(fp)` before using `ftruncate(fileno(fp))`. What happens next depends on how you opened the file, on whether you reposition the file stream before the next operation, and other details. At the o/s level, though, the file will have been truncated. – Jonathan Leffler Oct 28 '15 at 15:37
-
@JonathanLeffler: My mistake, there's only `fflush` and `freopen` :-) – Sebastian Oct 28 '15 at 15:56
-
Without a `fflush` before `ftruncate`, the file may not even be truncated when the write buffers are finally flushed (at `fclose`?). Without `freopen`, reading from the truncated file may give wrong results. But yes, if the asker does neither of those things your solution is even "safe". Just wanted to point out some possible caveats. – Sebastian Oct 28 '15 at 15:59
In Windows systems there's no header <unistd.h>
but yet you can truncate a file by using
FILE *f = ...;
_chsize( fileno(f), size);
-
5
-
-
-
1`fileno()` seems to be [deprecated](https://msdn.microsoft.com/library/ms235401.aspx), nowadays better to use `_fileno()`. – jdarthenay Apr 11 '16 at 13:07
-
2@AlexisWilke He did say "In Windows systems"; so yes, _chsize() is a Windows-only function. – Aaron Campbell Jul 07 '16 at 18:57
-
2`fileno()` is [standardized in POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fileno.html). Microsoft's "deprecation" is curious, at best. – Andrew Henle Jan 09 '17 at 14:23
-
1By Microsoft's strict interpretation, the POSIX and ISO standards are in conflict (and technically Microsoft is right). The leading underscore is a way to resolve the conflict. Using POSIX without standards-reconciling name tweaks is what's deprecated. The rest of the world gets by just fine without the reconciling name tweak though, so was it _really_ necessary? – Darryl Mar 03 '23 at 17:07
That's a function of your operating system. The standard POSIX way to do it is:
open("file", O_TRUNC | O_WRONLY);

- 730,956
- 141
- 904
- 1,278

- 30,615
- 9
- 51
- 60
-
14
-
1The question was clearly to truncate/shrink the file to a specific size. – salchint Aug 05 '20 at 04:49
-
1I agree this is not answer for the question but it is for the title. I came here trying to truncate to 0 bytes and the title has match to my search on google, so it's valid a +1 vote I think since mention a standard. – Enrique René Aug 18 '20 at 01:58
-
-
If you don't want it open afterwards, use `truncate("file", 0);` to set its length to zero. It's a POSIX function. But yeah, if you want the file open afterwards, like a shell `foo > file` redirect would, this is what you want. – Peter Cordes Apr 06 '22 at 07:23
If this is to run under some flavor of UNIX, these APIs should be available:
#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
According to the "man truncate" on my Linux box, these are POSIX-conforming. Note that these calls will actually increase the size of the file (!) if you pass a length greater than the current length.

- 4,610
- 23
- 30
<edit>
Ah, you edited your post, you're using C. When you open the file, open it with the mode "w+" like so, and it will truncate it ready for writing:
FILE* f = fopen("C:\\gabehabe.txt", "w+");
fclose(file);
</edit>
To truncate a file in C++, you can simply create an ofstream object to the file, using ios_base::trunc as the file mode to truncate it, like so:
ofstream x("C:\\gabehabe.txt", ios_base::trunc);

- 32,196
- 6
- 66
- 89

- 493
- 3
- 10
-
fopen will truncate contents of the file "gabehabe.txt" and position file pointer to the start, right? But will it empty the contents of the file before repositioning the file pointer? – Arpith Mar 26 '13 at 06:44
-
@Arpith: Yes, `"w"` or `"w+"` will truncate the file. https://man7.org/linux/man-pages/man3/fopen.3.html (`"w+"` opens for read+write, so you can write, seek, and read what you wrote. For write-only, omit the `+`). To open with the ability to write but without truncating, use `"a"` or `"a+"` (append) or `"r+"`. – Peter Cordes Apr 06 '22 at 07:29
If you want to truncate the entire file, opening the file up for writing does that for you. Otherwise, you have to open the file for reading, and read the parts of the file you want to keep into a temporary variable, and then output it to wherever you need to.
Truncate entire file:
FILE *file = fopen("filename.txt", "w"); //automatically clears the entire file for you.
Truncate part of the file:
FILE *inFile = fopen("filename.txt", "r");
//read in the data you want to keep
fclose(inFile);
FILE *outFile = fopen("filename.txt", "w");
//output back the data you want to keep into the file, or what you want to output.
fclose(outFile);

- 143,180
- 12
- 188
- 271

- 2,251
- 16
- 16
-
7This is a very inefficient way to perform this. @Jonathan Leffler's method is much preferable, and if your platform doesn't allow it, at least do a write/rename cycle, to prevent dataloss in the event of a crash (copy data to new file under temp name, then swap the names (atomicly if possible), then delete the old file) – derobert May 18 '09 at 17:51
-
plus if the file doesn't exist fclose has undefined behaviour – Jean-François Fabre Jan 01 '19 at 11:35