Por que o FWRITE está escrevendo mais do que eu digo?
Pergunta
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));
resultado:
0
25755
25868
o que está acontecendo? A gravação está definida como 25755, e eu digo a Fwrite para escrever muitos bytes em um arquivo, que está no começo, e depois estou em uma posição além de 25755?
Solução
Se você estiver em um sistema DOSSH (digamos, Windows) e o arquivo não for aberto no modo binário, as finais de linha serão convertidas automaticamente e cada "linha" adicionará um byte.
Então, especifique "wb"
como o modo em vez de apenas "w"
Como @Caf aponta. Isso não terá efeito nas plataformas do Unix, e fará a coisa certa sobre os outros.
Por exemplo:
#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;
}
Com 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
Com Cygwin GCC:
/cygdrive/c/Temp $ gcc y.c -o y.exe /cygdrive/c/Temp $ ./y.exe 02
Outras dicas
Pode depender do modo em que você abriu o arquivo. Se você o abrir como um arquivo de texto, então \n
pode ser escrito como \r\n
nos sistemas DOS/Windows. No entanto, ftello64()
provavelmente apenas dá o ponteiro de arquivo binário, o que contaria no extra \r
personagens escritos. Tente limpar o outbuf[]
de qualquer \n
dados ou tente abrir o arquivo out como binário ("wb"
ao invés de "w"
).
A variável write
é não inicializado e, portanto, o tamanho da matriz e o valor escrito será essencialmente aleatório.
Interessante. Funciona bem no Windows VC ++, embora ftello64
substituído por ftell
.