20
FILE *out=fopen64("text.txt","w+");
unsigned int write;
char *outbuf=new char[write];
//fill outbuf
printf("%i\n",ftello64(out));
fwrite(outbuf,sizeof(char),write,out);
printf("%i\n",write);
printf("%i\n",ftello64(out));

output:

0
25755
25868

what is going on? write is set to 25755, and I tell fwrite to write that many bytes to a file, which is at the beginning, and then im at a position besides 25755?

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
zacaj
  • 1,987
  • 1
  • 19
  • 39

4 Answers4

33

If you are on a DOSish system (say, Windows) and the file is not opened in binary mode, line-endings will be converted automatically and each "line" will add one byte.

So, specify "wb" as the mode rather than just "w" as @caf points out. It will have no effect on Unix like platforms and will do the right thing on others.

For example:

#include <stdio.h>

#define LF 0x0a

int main(void) {
    char x[] = { LF, LF };

    FILE *out = fopen("test", "w");

    printf("%d", ftell(out));
    fwrite(x, 1, sizeof(x), out);
    printf("%d", ftell(out));

    fclose(out);
    return 0;
}

With VC++:

C:\Temp> cl y.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

y.c
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:y.exe

C:\Temp> y.exe
04

With Cygwin gcc:

/cygdrive/c/Temp $ gcc y.c -o y.exe

/cygdrive/c/Temp $ ./y.exe
02
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
  • 3
    ...and you open in binary mode by using `"wb"` instead of `"w"` in `fopen()`. – caf Oct 19 '09 at 00:19
  • Based on the OP's (slight) presence in the **[mingw]** and **[cygwin]** tags, I suspect this is the answer. – Chris Lutz Oct 19 '09 at 00:20
  • That's curious because **cygwin** setup asks which type of line endings to use (and recommends Unix style). – Sinan Ünür Oct 19 '09 at 00:21
  • 1
    @Sinan - Yes, but MinGW will probably use the native line endings, thus causing slight confusion when switching between the two environments. – Chris Lutz Oct 19 '09 at 00:23
  • "Doing the right thing on others" is not the right way to think about it. DOS/CPM and UNIX just made different decisions in their architecture. DOS decided to separate the concept of carriage return and line feed while UNIX decided to merge the concepts just in the line feed character. The fact that there is no real difference between "wb" and "w" in UNIX means that you can't make "mysterious mistakes" with respect to opening and closing files in the "wrong mode". OTOH, DOS separates the concepts of line feed and carriage return which matches up with line printer semantics. – Paul Hsieh Oct 19 '09 at 20:42
  • It should be clear from the context that "the right thing" is platform-dependent and differ from one environment to another on the same computer. – Sinan Ünür Jan 18 '23 at 11:27
4

It may depend on the mode in which you opened the file. If you open it as a text file, then \n may be written as \r\n in DOS/Windows systems. However, ftello64() probably only gives the binary file pointer, which would count in the extra \r characters written. Try clearing the outbuf[] of any \n data or try opening the out file as binary ("wb" instead of "w").

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
Paul Hsieh
  • 1,466
  • 7
  • 9
2

The variable write is uninitialized and so the size of the array and the amount written will be essentially random.

Graeme Perrow
  • 56,086
  • 21
  • 82
  • 121
  • I suspect it's initialized in the real code and the OP is just being overly-protective of posting production code on a public website. – Chris Lutz Oct 19 '09 at 00:38
  • Yes, after re-reading the question I agree this is not likely the cause of the original problem - I think Sinan's answer is probably right. But just in case it _is_ a direct copy of the original code, I'll leave my answer here. – Graeme Perrow Oct 19 '09 at 13:20
0

Interesting. Works fine on Windows VC++, albeit ftello64 replaced with ftell.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
John Lockwood
  • 3,787
  • 29
  • 27