Anuncios Google

Error al leer archivos (Bucle Infinito)

int LeerDatos(ifstream &F,string nombre,Vector &Datos)
{
      // Abrimos el archivo indicado por el nombre
 
      F.open(nombre.c_str());
      int i = 0;
 
      // Si ha habido un error al abrir el archivo, se devuelve
 
      if (!F)
      {
                 return ERROR;
      }
      else
      {
          /* Sino, se empieza a leer hasta que se alcanza el final del fichero (Eof)
          *  En teoria deberia funcionar, pero se queda en un bucle infinito no se porque...
 
          */
 
          while(!F.eof())
          {
 
          // Uso getline para leer texto
 
           getline(F,Datos[i].Titulo);
           getline(F,Datos[i].Autor);
 
           // Uso F>> para leer el resto de los datos 
 
           F>>Datos[i].Precio;
           F>>Datos[i].Fecha.Dia;
           F>>Datos[i].Fecha.Mes;
           F>>Datos[i].Fecha.Anyo;
           F.ignore();
 
           // Incremento el numero de elementos
 
           i++;
 
 
          }
 
          // Cuando he terminado de leer, cierro el archivo y devuelvo el numero de elementos
 
          F.close();
          return i;
      }    
 
}

 

Mi idea es que lea la información del archivo y lo vaya guardando en la estructura hasta que llegue al final del archivo pero se queda "pillado".

 

La estructura de los datos en el fichero es la siguiente:

 

Título
Autor
Precio Dia Mes Anyo


Anuncios Google

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Almamu

Si estás haciendolo en C++

Si estás haciendolo en C++ esto debería de servirte:

// Las estructuras de los datos
struct __FECHA__
{
	int d;
	int m;
	int y;
};
 
struct __DATOS__
{
	__FECHA__ Fecha;
	int precio;
	char* autor;
	char* titulo;
};
 
// Función para leer los datos
int LeerDatos( const char* nombre, std::vector<__DATOS__*> &datos )
{
	FILE* fp = fopen( nombre, "rb+" ); // Abrimos el archivo pasado en nombre
	int i = 0;
 
	// Fallo al abrir el archivo...
	if( fp == NULL )
	{
		return 0;
	}
 
	// Tambien deberias de comprobar ferror, pero eso solo sería en casos raros
	while( !feof( fp ) ) // Mientras no estemos en el final del archivo
	{
		__DATOS__* data = new __DATOS__();
 
		fread( &data, sizeof( __DATOS__ ), 1, fp );
		datos.push_back( data );
 
		i ++;
	}
 
	fclose( fp );
 
	return i;
}

Necesitas incluir stdio.h, pero con esto debería bastar, eso si, debes de guardar usando funciones de la misma librería. No lo he comprobado porque no tengo el compilador aquí, pero debería de funcionar...


Lo siento, pero no me vale.

Lo siento, pero no me vale. En tu ejemplo estas leyendo la estructura de un fichero binario, y yo quiero rellenarla con un fichero de texto (*.txt) que haya rellenado el usuario. Pero se agradece la ayuda ;)

 

Por cierto unas consejos:

- Es más comodo usar una variable string que una variable char (así te olvidas de los punteros y te permite hacer más operaciones que los chars).

- Los vectores se pasan por referencia siempre, no hace falta que pongas un &.

 

Imagen de Loopin

Y cual es la diferencia entre

Y cual es la diferencia entre un archivo binario, y uno de texto? Un archivo de texto no es mas que un archivo binario cuyas funciones de lectura y escritura encapsulan algoritmos que se encargan de trabajar con caracteres ASCII para "facilitar" la labor, pero no dejan de ser secuencias de bytes uno detras de otro.

En lo de usar string, tienes razon, pero eso ya es cuestion de cada uno. AlmamuPP tengo entendido que es coder de C, por lo que de clases nanay, esta acostumbrado a trabajar con tipos base, o en su defecto con struct, como ha puesto en su ejemplo.

Sin embargo, eso de que los vectores siempre se pasan por referencia, no se donde lo has leido, pero no es cierto. Si no se le pone un & se hace una copia local del mismo, con el consiguiente costo computacional que conlleva, si no es estrictamente necesaria dicha copia.

Te recomiendo usar funciones de C++, o de C, pero no mezclar, para evitar quebraderos de cabeza. Lo digo por lo del getline(flujo, datos), que es una función de C, cuando puedes usar flujo.getline(datos).

En tu bucle de lectura veo un par de cosas que no tienes en cuenta. Estas dando por hecho que no va a haber errores de lectura, poniendo la comprobacion de fin de archivo solo como condicion de salida del bucle. Ten cuidado con el >>. Desconozco el tipo de dato que usas para Precio, Dia etc.. pero si son de tipo entero, o float o lo que sea, tendras que parsearlo a entero o float (ya que deduzco que ha sido escrito en modo texto, y no los bytes que componen el valor).

Asi a simple vista, creo que teniendo estas cosas en cuenta deberia funcionar.

Un saludo!

 


Imagen de Almamu

Realmente se tanto C como

Realmente se tanto C como C++, pero no uso clases en las estructuras porque al guardarlas en archivos te van a dar muchos problemas, puesto que las clases no se pueden guardar en archivos por el metodo con puntero FILE y las funciones de stdio. Ademas que usar estructuras para guardar cosas en los ficheros te evita muchos problemas, además de que no tienes que ir escrbiendo uno a uno cada dato al archivo, simplemente das la direccion de memoria de la estructura y el tamaño en bytes.


Imagen de joserc87

Clases y ficheros.

Es cierto que usar FILE y clases es un coñazo, pero para eso está la clase ofstream. Si en la clase implementas el operador << puedes hacer cosas como:

MiClase c1, c2, c3;
ofstream fo ("fichero.txt");
fo << c1 << c2 << c3;
fo.close ();

Igualmente puedes implementar el operador >> para leer archivos. Eso te da una generalidad bestial, porque puedes hacer, por ejemplo, un cout de una clase.

Saludos!


Be pointer my friend...

Dennis Ritchie. Padre de C y cocreador de UNIX.

R.I.P.

 

Bueno, si leyese en binario

Bueno, si leyese en binario tendría que añadir los saltos de linea, los espacios y ademas hacer una traducción texto-binario. Un pelín complicado teniendo los ficheros de texto disponibles.

 

Los vectores que yo sepa se pasan por referencia, puedes comprobarlo modificando el vector dentro de la misma funcion:

 

typedef int Vector[100];
 
void SumarVector(Vector suma)
{
  Suma[0] = 0;
  Suma[0] += 2;
}
 
int main()
{
 
  Vector Suma;
  Suma[0] = 1;
 
  SumaVector(Suma);
  cout<<Suma[0];
 
  system("PAUSE");
  return 0;
}

 

A lo mejor es solo en C++ pero a mi me funciona...

 

Y si es cierto, debería comprobar errores de lectura. Los valores Precio, Dia, Mes y Anyo  son enteros y float. Pero eso no tiene nada que ver porque se lee igual (la prueba es el cin). Además acabo de hacer el cambio a string y sigue igual :(

 

Dejo aquí el archivo que uso como prueba, aunque en teoría debería estar bien:

http://www.megaupload.com/?d=K0VDFQ3J

 

Y esta es la estructura de datos:

struct fecha
{
       int Anyo,Mes,Dia;
};
 
struct Biblioteca
{
       string Titulo, Autor;
       float Precio;
       fecha Fecha;
};
 
typedef Biblioteca Vector[TAM];

 

EDITO:

 

Solucionado, había reservado 1000 espacios en el vector y en el archivo habia unos 1800 elementos T_T

 

 

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.