Deseo abrir un archivo con la «a+b», es decir, si no existe, se crea automáticamente, pero si lo hace yo no lo desea sobrescribirlo. Quiero ser capaz de leer y escribir en el archivo.

El archivo es binario, y quiero guardar los registros de una determinada struct en ella. Así que me quiero hacer fseek() para el disco que desee y, a continuación, guarde el registro mediante fwrite().

El código es como sigue (MyRecord es un typedef a un struct, mientras que FILENAME es un #define para el nombre del archivo):

int saveRecord(MyRecord *pRecord, int pos)
{
    FILE* file = fopen(FILENAME, "a+b");
    if (file == NULL)
    {
        printf("Unable to open file %s\n", FILENAME);
        return 0;
    }

    fseek(file, pos * sizeof(MyRecord), SEEK_SET);
    fwrite(pRecord, sizeof(MyRecord), 1, file);
    fclose(file);
    return 1;
}

Sin embargo, este código sólo se anexa el registro al final del archivo, incluso si me puse pos a 0. ¿Por qué no fseek() con SEEK_SET de trabajo en modo append?

Sé que puedo simplemente abrir con «r+b» y si no logra abrir con «wb», pero me gustaría saber por qué no funciona y por qué fseek() con SEEK_SET está dejando el puntero de archivo al final. Cualquier referencia a los lugares donde este comportamiento se documenta apreciado (porque no podía encontrar ninguna, o yo estoy usando las palabras claves equivocadas).

OriginalEl autor jbx | 2011-04-03

3 Comentarios

  1. 18

    Eso es porque en a modo, la escritura a la FILE* siempre anexa a la final. fseek solo ajusta el puntero de lectura en este modo. Esto está documentado en el estándar de C, 7.19.5.3 fopen:

    Abrir un archivo con modo append ('a' como primer carácter en el modo de argumento)
    hace que todos los posteriores escribe en el archivo a ser forzado a las actuales de fin de archivo,
    independientemente de intervenir las llamadas a la fseek función.

    Gracias, la respuesta que necesitaba.

    OriginalEl autor Fred Foo

  2. 4

    Llanura C no tiene ninguna manera coherente para lograr lo que desea. Si estás en un sistema POSIX o nada remotamente cerca, puede utilizar fd=open(FILENAME, O_CREAT|O_RDRW, 0666) y, a continuación,fdopen(fd, "rb+").

    Edición: Otra cosa que usted puede probar, con un simple C:

    f = fopen(FILENAME, "a+b");
    if (!f) /* ... */
    tmp = freopen(0, "r+b", f);
    if (tmp) f = tmp;
    else /* ... */
    Sí, supongo que podría funcionar. Necesito esto para trabajar en pura ANSI C, aunque. Todavía +1 para ti por la buena alternativa.
    Has probado el freopen solución? Ni idea de si funciona en la práctica (freopen está mal especificado y en teoría, podría ser inútil), pero puede estar bien.

    OriginalEl autor R..

  3. 4

    Uso de la «r+b» modo de reserva y a la «w+b» si se produce un error.

    La «a+b» modo, permite leer y anexar; la «r+b» permite la lectura y escritura aleatorias.

    La documentación para fopen describe cómo el archivo se comporta con los diferentes modos.

    Esto tiene una condición de carrera que va a darle una paliza a su archivo.
    de qué raza, condición? debería decir «reserva «wb» si se produce un error con errno == ENOENT«
    Estoy asumiendo una multitarea OS que otro proceso podría crear el archivo y llenarlo con los datos después de la primera fopen falla, pero antes de la segunda fopen intento. Si OP es el de trabajar con un sistema embebido o cualquier sistema cerrado donde se sabe que esto no ocurra, puede que no sea un problema.
    Veo a @R.. gracias. Si eso es un problema fwrite a la misma posición al mismo tiempo por diferentes procesos también es un problema; el OP puede utilizar el mismo método para administrar ambas cuestiones.

    OriginalEl autor pmg

Dejar respuesta

Please enter your comment!
Please enter your name here