Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

223
Vistas
Diferente comportamiento de fwrite entre Linux y Windows

Tengo un pequeño programa de ejemplo escrito en C. Tengo un main que llama a una función writeFile que escribe algunos números en un archivo binario. Luego llamo overwrite para reemplazar 0 con 1 y finalmente imprimo el resultado.

Este es el código:

 #include <stdio.h> /* Print the content of the file */ void printFile(){ printf("Read test.dat:\n"); int r; FILE* fp = fopen("test.dat", "rb+"); if(fp) { while(fread(&r,sizeof(int),1,fp)){ printf("%d\n", r); } } fclose(fp); } /* Replace 0 with 1 */ void overwrite(){ int r; FILE *fp = fopen("test.dat", "rb+"); if (fp) { int i=0; while (i < 4 && fread(&r, sizeof(int), 1, fp)) { i++; if (r == 0) { r = 1; fseek(fp,-sizeof(int),SEEK_CUR); fwrite(&r,sizeof(int),1,fp); } } } fclose(fp); } /* Create original file */ void writeFile() { int b, b1, b2, b3, b4; b = 3; b1 = 2; b2 = 0; b3 = 4; FILE *fp = fopen("test.dat", "wb"); if (fp) { fwrite(&b, sizeof(int), 1, fp); fwrite(&b1, sizeof(int), 1, fp); fwrite(&b2, sizeof(int), 1, fp); fwrite(&b3, sizeof(int), 1, fp); } fclose(fp); } int main() { writeFile(); printf("---------BEFORE--------\n"); printFile(); printf("-----------------------\n"); printf("Overwriting...\n"); overwrite(); printf("---------AFTER---------\n"); printFile(); return 0; }

Este código funciona con Linux, pero cuando ejecuto el mismo código en Windows, el resultado es este:

 ---------BEFORE-------- Read test.dat: 3 2 0 4 ----------------------- Overwriting... ---------AFTER--------- Read test.dat: 3 2 1 2

No solo el 0 fue reemplazado por 1, sino que también cambió el último número. ¿Alguien puede ayudarme a entender por qué sucede esto?

Otro problema es que en la overwrite debo usar i para parar el while porque sin i<4 obtengo un bucle infinito (solo con Windows).

Probé este código en Windows 8.1 compilado con gcc 4.8.1 (de MinGW). En mi máquina Linux probé el código con gcc 5.1.1.

Gracias a todos,

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Es porque necesita fflush() después de fwrite() , ya que no debe llamar a fread() después de llamar a fwrite() sin una llamada intermedia a fflush() ,

Esta es la sección de la norma que es relevante en este caso

7.21.5.3 La función fopen

  1. Cuando se abre un archivo con el modo de actualización ( '+' como el segundo o tercer carácter en la lista anterior de valores de argumento de modo), tanto la entrada como la salida se pueden realizar en el flujo asociado. Sin embargo, la salida no debe ser seguida directamente por una entrada sin una llamada intermedia a la función fflush o a una función de posicionamiento de archivos ( fseek , fsetpos o rewind ), y la entrada no debe ser seguida directamente por una salida sin una llamada intermedia a un posicionamiento de archivos. función, a menos que la operación de entrada encuentre el final del archivo. Abrir (o crear) un archivo de texto con el modo de actualización puede abrir (o crear) un flujo binario en algunas implementaciones.

Es extraño que esta sección esté dentro de la función fopen() ya que involucra fread() y fwrite() , que es donde estaba buscando una respuesta.

También puede ver que mi respuesta anterior funcionó, pero no por la razón que indiqué en ella, sino que la explicación se encuentra en el párrafo anterior.

over 4 years ago · Santiago Trujillo Denunciar

0

Estados de MSDN para Stream I/O :

La entrada puede seguir a la salida directamente solo con una llamada intermedia a fflush o a una función de posicionamiento de archivos ( fseek , fsetpos o rewind ). La salida puede seguir a la entrada sin una llamada intermedia a una función de posicionamiento de archivos si la operación de entrada encuentra el final del archivo.

Entonces tendrías que llamar a fflush() después de llamar a fwrite:

 void overwrite() { FILE *fp = fopen("test.dat", "rb+"); if (fp) { int r; while (fread(&r, sizeof(int), 1, fp) == 1) { if (r == 0) { r = 1; fseek(fp,-sizeof(int),SEEK_CUR); fwrite(&r,sizeof(int),1,fp); fflush(fp); /* Flush here */ } } fclose(fp); /* Also: call fclose() only when fopen() succeeded */ } }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda