fstream y fopen y sus modos

Iniciado por patilanz, 14 Abril 2014, 15:41 PM

0 Miembros y 1 Visitante están viendo este tema.

patilanz

Hola tengo una duda respecto a los modos de fopen ya que estoy haciendo un programa que actualiza los dados de un archivo pero que funciona de una forma muy rara.
Asi no funciona:
Código (cpp) [Seleccionar]
ofstream file(fName,ios::binary | ios::out);
file.seekp((100+sizeof(unsigned int))*--p);
char name[100];
string n=d.showName();
int length=n.size()>99?99:n.size();
strncpy_s(name,n.data(),length);
name[length]='\0';
file << name;
unsigned int years=d.showYears();
file.write((char*)&years,sizeof(unsigned int));
if(file.fail())return false;
return true;

Si cambio ios::out por ios::ate tampoco funciona ya que reemplaza lo ya escrito y no lo cambia.

Si utilizo ios::binary | ios::out si funciona pero no se porque ya que out es para coger datos del archivo ??
Me lo pueden explicar?

Gracias y saludos :)

eferion

ios::in indica que vas a abrir el archivo para leerlo
ios::out indica que vas a abrir el archivo para escribirlo
ios::ate únicamente posiciona el cursor al final del archivo... no indica si vas a leer o a escribir

Código (cpp) [Seleccionar]
file.seekp((100+sizeof(unsigned int))*--p);

Deberías querer un poco más tu código y evitar líneas de este estilo... te pueden dar bastantes problemas si confundes la sintaxis lo más mínimo... y depurar una línea así puede no ser trivial.


patilanz

A pues, gracias por responder yo había leído muchas veces en la documentación y ponía esto pero no se porque me había confundido así ya que esto lo había hecho mucho antes y sabia trabajar con archivos.
Entonces es out porque sale del programa para entrar en el archivo, yo pensaba que sale del archivo. Gracias ahora ya lo entiendo.
Pero ate si no indica si se lee o escribe debería de funcionar ya que lo utilizo con un ofstream para escribir.

Con respecto a la sintaxis tu como lo harias? Vas a crear una variable para los bytes a pasar? y luego --p a parte?
Yo con la sintaxis casi nunca me confundo.


eferion

Cita de: patilanz en 14 Abril 2014, 17:22 PM
Yo con la sintaxis casi nunca me confundo.

El problema es que ese "casi", en determinadas líneas, puede suponer un problema:

int valor = variable1+++ variable2;
int valor = variable1++ +variable2;
int valor = variable1+ ++variable2;
int valor = variable1 +++variable2;
int valor = variable1+++variable2;


los cinco códigos se parecen como gotas de agua... ponte tu a descubrir que el espacio lo has puesto en un sitio en vez de en otro... y claro, evaluar las variables en mitad de la línea no es trivial...

Efectivamente, sería más legible y menos propenso a errores sacar el --p fuera de esa expresión... no hay que ser tacaño a la hora de escribir líneas de código si la idea es mejorar la legibilidad y el mantenimiento futuro del código.

Cita de: patilanz en 14 Abril 2014, 17:22 PM
Pero ate si no indica si se lee o escribe debería de funcionar ya que lo utilizo con un ofstream para escribir.

El problema es que con ate no indicas si vas a leer o escribir... en este caso la función puede que haga uso del mecanismo por defecto ( que seguro que no sabes cual es ) o puede que directamente no permita realizar operaciones sobre ese recurso porque no tiene flags de entrada / salida definidos... para saber el comportamiento concreto toca mirar la documentación de la STL.

patilanz

Gracias voy a intentar a seguir mas orden cuando escribo el código  ;D

CitarEl problema es que con ate no indicas si vas a leer o escribir... en este caso la función puede que haga uso del mecanismo por defecto
En la STL pone que en ofstream out siempre esta definido, por lo tanto supongo que ate también es out.

Antes me dijiste que out es para escribir y in para leer pero entonces porque se produce esto:

Código (cpp) [Seleccionar]
Sobrescribe todo: ofstream file(fName,ios::binary);
Sobrescribe todo: ofstream file(fName,ios::binary | ios::ate);
Sobrescribe todo: ofstream file(fName,ios::binary | ios::ate | ios::out);
Funciona bien: ofstream file(fName,ios::binary | ios::in);


Al usar in con ofstream que se para escribir y in es para leer funciona bien pero en los otros casos no. Porque ??

Perdón si soy muy pesado pero no me queda claro. Gracias por tu paciencia.

eferion

Cita de: patilanz en 14 Abril 2014, 19:03 PM
En la STL pone que en ofstream out siempre esta definido, por lo tanto supongo que ate también es out.

Ese valor por defecto lo vas a encontrar siempre y cuando no lo sobreescribas.

Si tu estableces una opción personalizada para abrir un archivo, esta nueva configuración va a sustituir a la que viene por defecto.

Cita de: patilanz en 14 Abril 2014, 19:03 PM
Antes me dijiste que out es para escribir y in para leer pero entonces porque se produce esto:

Es sencillo. Para escritura, el flag que permite actualizar es ios::app ( "app" de "append" ). Cualquier intento de abrir un fichero para escritura sin la opción "app" provoca el borrado del contenido del fichero, ya que no has indicado que quieres conservar el contenido.

La última opción te mantiene el contenido del archivo porque lo has abierto en modo lectura... obviamente si quieres leer el contenido no queda bien que la librería te lo borre.

patilanz

CitarSi tu estableces una opción personalizada para abrir un archivo, esta nueva configuración va a sustituir a la que viene por defecto.
CitarLa última opción te mantiene el contenido del archivo porque lo has abierto en modo lectura... obviamente si quieres leer el contenido no queda bien que la librería te lo borre.
Si utilizo ofstream para escribir pero sustituyo la opcion por defecto out por in no deberia de poder leer ni escribir ya que no tiene permisos para escribir ni funciones para leer ya que es ofstream y no ifstream.
Código (cpp) [Seleccionar]
ofstream("file",ios::binary | ios::in);

Esto funciona como si tiene append asignado pero sin haberle puesto permisos o modos para escribir.

eferion

#7
Cita de: patilanz en 15 Abril 2014, 11:05 AM
Esto funciona como si tiene append asignado pero sin haberle puesto permisos o modos para escribir.

Yo no se hasta que punto ese código supone una solución portable...

Con esto quiero decir... es posible que con un compilador diferente ( usando el mismo SO ) el resultado final sea distinto.

ivancea96

Cita de: patilanz en 15 Abril 2014, 11:05 AM
Si utilizo ofstream para escribir pero sustituyo la opcion por defecto out por in no deberia de poder leer ni escribir ya que no tiene permisos para escribir ni funciones para leer ya que es ofstream y no ifstream.

ios::out es una opción que tiene ofstream por defecto. No estas sustituyendo el ios::out por el ios::in, simplemente estás agregando el ios::in, por tanto, seguirá con permiso de escritura.