Hola esta es la siquiente duda que tengo.
quiero hacer esto.
(http://3.bp.blogspot.com/-FOrB1JXbeEg/UzEfM4pkwRI/AAAAAAAAAmE/CH66HSHQDVY/s1600/ArchivoDeTextoAbinario.png)
No se como pasar lo que tengo en el txt a un archivo binario. lo de listar si se como hacerlo a si que lo que mas me interesa es hacer la convercion.
y tengo esto
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <iomanip>
#include "Cliente.h"
using namespace std;
int ArchivoBin();
int main(int argc, char *argv[])
{
//Archivo de texto
ifstream lectura("Empleados.txt",ios::in);
if(!lectura)
{
cout << "Error. No se pudo"
<< " abrir el archivo."
<< endl;
system("pause");
return -1;
} // Verificación del archivo.
// 2. Leer información.
int idCliente=0;
char nombre[20], apellido[20];
double ingreso;
cout << '\n'
<< setw(10) << "Codigo"
<< setw(15) << "Nombre"
<< setw(15) << "Apellido"
<< setw(15) << "Ingreso L."
<< setw(20) << "Archivo Texto"
<< fixed << setprecision(2)
<< endl;
for(int i=0; i<55; i++)
cout << '=';
cout << endl;
lectura >> idCliente
>> nombre
>> apellido
>> ingreso;
while(!lectura.eof())
{
cout << setw(10) << idCliente
<< right << setw(15) << nombre
<< setw(15) << apellido
<< setw(15) << ingreso << endl;
lectura >> idCliente
>> nombre
>> apellido
>> ingreso;
}
lectura.close();
ArchivoBin();
system("PAUSE");
return EXIT_SUCCESS;
}
int ArchivoBin()
{
ofstream salida ("Empleados.bin", ios::binary);
//Archivo de texto
ifstream lecturaBin("Empleados.bin", ios::binary);
if(!lecturaBin)
{
cout << "Error. No se pudo"
<< " abrir el archivo."
<< endl;
system("pause");
return -1;
} // Verificación del archivo.
// 2. Leer información.
Cliente registro;
int idCliente=0;
char nombre[20], apellido[20];
double ingreso;
cout << '\n'
<< setw(10) << "Codigo"
<< setw(15) << "Nombre"
<< setw(15) << "Apellido"
<< setw(15) << "Ingreso L."
<< setw(20) << "Archivo Binario"
<< fixed << setprecision(2)
<< endl;
for(int i=0; i<55; i++)
cout << '=';
cout << endl;
lecturaBin.seekg((idCliente - 1) * sizeof(Cliente));
lecturaBin.read(reinterpret_cast<char *>(®istro), sizeof(Cliente));
while(!lecturaBin.eof())
{
cout << setw(10) << idCliente
<< right << setw(15) << nombre
<< setw(15) << apellido
<< setw(15) << ingreso << endl;
lecturaBin.read(reinterpret_cast<char *>(®istro), sizeof(Cliente));
}
lecturaBin.close();
return 0;
}
espero puedan ayudarme.
estos son los datos en el .txt por si quieren provarlo
1 Davolio Nancy 900
2 Fuller Andrew 678
3 Leverling Janet 3000
4 Peacock Margaret 78564
5 Buchanan Steven 7865
6 Suyama Michael 8000
7 King Robert 700
8 Callahan Laura 2000
9 Dodsworth Anne 12345
y mi salida es esta.
(https://images-blogger-opensocial.googleusercontent.com/gadgets/proxy?url=http%3A%2F%2F3.bp.blogspot.com%2F-Y1QtfShSn_I%2FUzEg4RCfgmI%2FAAAAAAAAAmQ%2FdxVw0p1rHUI%2Fs1600%2FSalida.png&container=blogger&gadget=a&rewriteMime=image%2F*)
Entendiendo por archivo de texto uno con un contenido legible tal que
100 Pedro Rodriguez 2000
101 Laura Fernandez 1890
102 Sergio Berbes 2685
Pasar esto a binario es tan "sencillo" como volcar la información al fichero sin tratar previamente. Es decir, el código, por ejemplo, en un archivo de texto lo almacenas como si fuese un string, con X caracteres, uno por dígito... en binario este mismo campo ocuparía 4 bytes independientemente del valor del código ( 4 bytes = tamaño por defecto de un int ). Esto es aplicable a floats, booleanos, y demás tipos básicos. En el caso de las cadenas de texto, éstas no sufren ningún cambio.
Dicho esto, para generar un fichero binario desde C++ hay que pasarle un flag especial en la creación para que no haga las conversiones a string ( ios::binary ):
ofstream fichero( "fichero.bin", ios::out | ios::binary);
El resto del proceso es el mismo que para generar un fichero de texto normal.
Y para leer este archivo... pues lo mismo, el ifstream lo tienes que configurar con el flag ios::binary;
Si entiendo
Pero como le paso esos los datos al archivo de binario, ya intente el.
ofstream fichero( "fichero.bin", ios::out | ios::binary);
pero no me funciona. por que esta creando el fichero.bin, pero como le paso a ese fichero.bin los datos del txt.
si no es mucha molestia agradeceria algun ejemplo.
saludos y gracias por responder.
ofstream fichero("fichero.bin");
fichero.write((char*) & idcliente,sizeof(int));
Con eso ya escribes el idcliente en binario, se procede igual con las demás variables, con la excepción de las que son char*:
fichero.write(nombre,strlen(nombre));
Aunque esto haría lo mismo:
fichero<<nombre;
Si exacto asi tambien lo estaba tratando de hacer y mas facil.
fichero<<nombre;
creo que talvez lo que estoy haciendo mal puede ser esto.
fichero.write(nombre,strlen(nombre));
por que yo estoy leyendo en bin y como no hay datos primero tengo que escribirlos
bueno en este caso pasarlos de txt a binario intentare con lo que me indicas. y comento gracias por la ayuda.
todavía no me sale pero ya casi.
(https://images-blogger-opensocial.googleusercontent.com/gadgets/proxy?url=http%3A%2F%2F1.bp.blogspot.com%2F-DRrFm5NyRiE%2FUzE__hXWH1I%2FAAAAAAAAAmg%2FdEiBNHpaVNA%2Fs1600%2FHAC.png&container=blogger&gadget=a&rewriteMime=image%2F*)
No no. No tienes que "copiar" un fichero en otro.
Tienes que leer el contenido de uno de los archivos y escribir en el otro.
Lo que sucede es que escribir en binario requiere algún proceso adicional.
El proceso de grabación y lectura de binarios es un poco más escabroso en C++ con respecto a C.
Yo utilizo un par de funciones de ayudas ( me apoyo en templates para evitar reescribir código ):
#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
template< class T > void
binary_write( ostream& stream, const T& value )
{
stream.write( reinterpret_cast< const char* >( &value ), sizeof( T ) );
}
void
binary_write_string( ostream& stream, const string& value, int max_size )
{
int max = max_size - 1;
if ( value.length( ) < max )
max = value.length( );
stream.write( value.c_str( ), max );
for ( ; max < max_size; max++ )
stream << '\0';
}
template< class T > void
binary_read( istream& stream, T& value )
{
stream.read( reinterpret_cast< char* >( &value ), sizeof( T ) );
}
void
binary_read_string( istream& stream, string& value, int max_size )
{
value.clear( );
value.reserve( max_size );
int pos;
for ( pos = 0; pos < max_size; ++pos )
{
char c;
stream >> c;
if ( c == '\0' )
break;
value += c;
}
stream.ignore( max_size - pos - 1 );
}
int main()
{
ofstream fich( "text.txt", ios::out | ios::binary );
string text1 = "Prueba1";
string text2 = "Prueba2";
int dato = 1234;
binary_write_string( fich, text1, 10 );
binary_write_string( fich, text2, 10 );
binary_write( fich, dato );
fich.close( );
ifstream fich2 = ifstream( "text.txt", ios::in | ios::binary );
binary_read_string( fich2, text1, 10 );
binary_read_string( fich2, text2, 10 );
binary_read( fich2, dato );
cout << text1 << endl << text2 << endl << dato << endl;
}
En tu caso, para pasar de uno a otro primero tienes que leer el contenido del archivo de texto y después grabar el contenido en el archivo binario.
¿Escalabroso? Pero si es tan fácil como:
fichero.write((char*) & idcliente,sizeof(int));
Nolasco81, ¿qué código te genera esa captura?
Y por cierto, si lo que esperabas esque te saliesen 0 y 1 no va a suceder... La pantalla siempre solo muestra caracteres leíbles, no el valor de cada byte.
No No.
no pretendo que me salgan cero y unos si no como ves en la captura uno dice archivo de texto y el otro Binario el la parte donde dice archivo binaro tiene que salir lo mismo que de texto.
Eferion
es correcto tengo que leer los archivo del txt y escribirlos en el binario.
y despues mostrar los datos del txt y binario para comprobar que son los mismos.
y si esta instruccion es correcta.
fichero.write((char*) & idcliente,sizeof(int));
cuando solo es binario si no me equivoco.
este codigo me genera esta salida.
registro.setIdCuenta(idCliente);
registro.setNombre(nombre);
registro.setApellido(apellido);
registro.setIngreso(ingreso);
lecturaBin.seekp((idCliente - 1) * sizeof(Cliente));
lecturaBin.write(reinterpret_cast<char *>(®istro), sizeof(Cliente));
while(!lecturaBin.eof())
{
cout << setw(10) << idCliente
<< right << setw(15) << nombre
<< setw(15) << apellido
<< setw(15) << ingreso << endl;
lecturaBin.write(reinterpret_cast<char *>(®istro), sizeof(Cliente));
//lecturaBin >> idCliente
// >> nombre
// >> apellido
// >> ingreso;
}
El problema que tienes ( al menos uno de ellos ) es que los strings no se "deben" escribir alegremente en un archivo binario. El motivo es que no tiene un tamaño conocido y C++ no va a insertar un carácter de terminación en el archivo... si escribes un dos strings seguidos, en la lectura vas a leer los dos del tirón.
El ejemplo que te he puesto ( que se basa en unas funciones que encontré y mejoré hace ya unos años ) te permiten leer y escribir datos en archivos binarios de una forma sencilla y te permite despreocuparte del tipo de dato concreto... bueno si, el string tiene su función independiente... pero es así para permitir su lectura desde estructuras de C ( que suelen tener tamaño fijo ).
Se puede modificar el código fácilmente para que los strings no sean de tamaño fijo y que su lectura sea símplemente hasta encontrar el caracter nulo:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
template< class T > void
binary_write( ostream& stream, const T& value )
{
stream.write( reinterpret_cast< const char* >( &value ), sizeof( T ) );
}
template< > void
binary_write( ostream& stream, const string& value )
{
stream.write( value.c_str( ), value.length( ) );
stream << '\0';
}
template< class T > void
binary_read( istream& stream, T& value )
{
stream.read( reinterpret_cast< char* >( &value ), sizeof( T ) );
}
template< > void
binary_read( istream& stream, string& value )
{
value.clear( );
while ( true )
{
char c;
stream >> c;
if ( c == '\0' )
break;
value += c;
}
}
int main()
{
ofstream fich( "text.txt", ios::out | ios::binary );
string text1 = "Prueba1";
string text2 = "Prueba2";
int dato = 1234;
binary_write( fich, text1 );
binary_write( fich, text2 );
binary_write( fich, dato );
fich.close( );
ifstream fich2 = ifstream( "text.txt", ios::in | ios::binary );
binary_read( fich2, text1 );
binary_read( fich2, text2 );
binary_read( fich2, dato );
cout << text1 << endl << text2 << endl << dato << endl;
}
Hola gracias por contestar si lo mismo pienso que no es tan facil como se ve.
Dejame pruebo y analiso tu que me compartiste para entenderle mejor y comento como me fue.
saludos y gracias. por ayudarme, a los dos.
lecturaBin.write(reinterpret_cast<char *>(®istro), sizeof(Cliente));
Hay que diferenciar entre array de char y strings. Mis códigos partían de que eran char*.
Hazlo miembro a miembro, cuando llegues al string haces el << y insertas además el caracter nulo (o un espacio). Ese caracter sirve para que en la lectura se sepa cuando termina el string
Al leerlo igual con la función read miembro a miembro, para el string usas el >> y haces un ignore() (para descartar el caracter nulo que pusistes antes).
Efectivamente, no puedes meter una clase literalmente en el código. La razón es que las clases pueden tener más cosas aparte de los miembros ( por ejemplo información RTTI relativa a la herencia de las clases ).
En C estas cosas no pasan porque no existe la herencia, pero en C++...
Así que lo dicho, copia miembro a miembro y no deberías tener problemas.
probando y comento luego aunque es algo confuso para mi.
saludos y gracias.
// teniendo ...
registro.setIdCuenta(idCliente);
registro.setNombre(nombre);
registro.setApellido(apellido);
registro.setIngreso(ingreso);
// la escritura quedaria ...
binary_write( escrituraBin, registro.getIdCuenta( ) );
binary_write( escrituraBin, registro.getNombre( ) );
binary_write( escrituraBin, registro.getApellido( ) );
binary_write( escrituraBin, registro.getIngreso( ) );
Y lo mismo para la lectura
Despues de tanto me salio como momentas eferion lamentablemente no puedo poner una image ya que no me deja entrar a mi cuenta. saludos y gracias a todos por su ayuda y su tiempo. muchas gracias de verdad.
Mmmm, ¿"binary_write"? ¿No es lo mismo que:
fwrite( &campo, sizeof(tipo_del_dato_en_el_campo), 1, fPtr );
?
En efecto, pero eso es en C.
Cita de: amchacon en 26 Marzo 2014, 15:32 PM
En efecto, pero eso es en C.
Exacto. No puedes pretender crear un fichero con ofstream y escribir su contenido con fwrite.