tags:

views:

676

answers:

4
+3  Q: 

Truncate file

I am using fopen fseeko64 ftello64 fclose etc. to operating on a file.

How can I truncate a file? I know that there is no standard way to do this in C. All I want is some way that will work on any win32 platform. I'm using mingw gcc to compile.

Please note: I meant truncate the size of the file to a specified size, not make it 0 size. And using a trick like copy part to another file and delete/rename is not appropriate.

A: 

If you simply fopen() a file with the "w" argument, it will be truncated.

http://www.cplusplus.com/reference/clibrary/cstdio/fopen.html

Thomas
+1  A: 

You should be able to fopen with the "w" flag:

FILE *fh = fopen("file.txt","w");
if (fh != NULL) fclose(fh);

Following your clarification that you want to truncate the file at a specific point, you can do this with standard C functions such as (add suitable error checking):

FILE *fin = fopen ("input.txt","rb");
FILE *fout = fopen ("output.txt", "wb");
size_t sz = 100000; /* for 100,000 bytes */
char *buff = malloc (sz);
sz = fread (buff, 1, sz, fin);
fwrite (buff, 1, sz, fout);
free (buff);
fclose (fin);
fclose (fout);

Of course, if you have access to the Win32 headers and libraries (and I believe MinGW gives you this), you can use SetEndOfFile() as Adam Davis has suggested, since it does it in place, rather than having to create a new file and then rename it.

paxdiablo
Why are you using a pointer to a single character? You can use fgetc() and fputc() and just use a non-pointer (or not even a variable): for(int i = 0; i < 100000; i++) fputc(fgetc(fin), fout);
Chris Lutz
Which would result in 100,000 times as many function calls :-)
paxdiablo
Ah, there was some misreading. Sorry. (However, I don't think 100000 fgetc()s and fputc()s really take that long.)
Chris Lutz
Interesting, I was going to prove you wrong by writing sample programs but it appears you are right. Transfer of a 34M file actually takes longer (twice as long) with malloc and repeated fread(100k)/fwrite(100K) than with a repeated fgetc/fputc. So I'll wisely keep my mouth shut :-)
paxdiablo
+8  A: 

SetEndOfFile()

Get a handle to the file with write access, set the file pointer, then call SetEndOfFile().

Adam Davis
I think we have a winner here, @myforwik.
paxdiablo
A: 

As mentioned already, you can use fopen() with the "w" flag like:

FILE *f = fopen("file.txt", "w");

Also, if you already have the file opened, you can use the function freopen(), again with the "w" flag:

FILE *f = fopen("file.txt", "r");  //initial fopen() call
...
f = freopen("file.txt", "w", f);   //reopens "file.txt" and truncates it

http://www.cplusplus.com/reference/clibrary/cstdio/freopen.html

EDIT: After seeing you've edited your OP, I won't repost what Pax and Adam Davis has already put. Also, I'll confirm what Pax said, that the MinGW does give you access to the Win32 headers.

DeadHead