elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Como extraer datos de un txt y guardar en funcion de un valor en un binario??
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Como extraer datos de un txt y guardar en funcion de un valor en un binario??  (Leído 2,101 veces)
valeeen

Desconectado Desconectado

Mensajes: 46


Ver Perfil
Como extraer datos de un txt y guardar en funcion de un valor en un binario??
« en: 27 Enero 2016, 15:47 pm »

Muy buenas amigos,
para un ejercicio me piden que lea un txt que tenga la siguiente estructura:

nombre # renta nota

a partir de este txt, tengo que filtrar por los que tengan una renta menor que x (por ejemplo 10.000) y solo esos guardarlos en un archivo binario.

De momento lo que tengo hecho es lo que veis abajo, lo unico que he conseguido es que si pongo un "cout" pinto todas las lineas del txt, pero no consigo filtrar por el segundo valor y meter todo lo que cuadre en un archivo binario...

En el código que tengo quería probar a sacar el único nombre que tenia con el valor 6.000 pero no lo hace...

me podeis ayudar?

gracias!!

archivo .h:

Código
  1.  
  2. // main.h
  3.  
  4. #pragma once
  5.  
  6. #include <iostream>
  7. #include <fstream>
  8. #include <string>
  9. using namespace std;
  10.  
  11. #define MAX 50
  12.  
  13. typedef struct {
  14. char nombre[MAX];
  15. int renta;
  16. float nota;
  17. }lista;
  18.  
  19. int getLength(lista[]);
  20.  

archivo cpp
Código
  1. #include "Header.h"
  2.  
  3. void main()
  4. {
  5.  
  6.  
  7. lista persona;
  8. fstream archivo, archivodat;
  9. archivo.open("solicitudes.txt", ios::in);
  10. archivodat.open("aceptados.dat", ios::out | ios::binary);
  11. if (!archivo) {
  12. cout << "Error al leer archivo";
  13. }
  14. else {
  15. if (!archivodat)
  16. cout << "Error creando el archivo binario";
  17. else {
  18. archivo.getline(persona.nombre, MAX, '#');
  19. archivo >> persona.renta, ' ';
  20. if (persona.renta == '6000')
  21. {
  22. archivo >> persona.nota;
  23. while (!archivo.eof()) {
  24. archivo.getline(persona.nombre, MAX, '#');
  25. archivo >> persona.renta, ' ';
  26. archivo >> persona.nota;
  27. archivodat.write(reinterpret_cast<const char *>(&persona), sizeof(lista));
  28. }
  29. archivodat.close();
  30. }
  31.  
  32. }
  33. archivo.close();
  34. }
  35.  
  36. system("pause");
  37. }
  38.  


« Última modificación: 27 Enero 2016, 15:49 pm por valeeen » En línea

class_OpenGL


Desconectado Desconectado

Mensajes: 437

Si usas Direct3D, no eres mi amigo :P


Ver Perfil
Re: Como extraer datos de un txt y guardar en funcion de un valor en un binario??
« Respuesta #1 en: 27 Enero 2016, 17:54 pm »

Si no he entendido mal, lo que quieres hacer es guardar la estructura 'persona' como binario en un archivo. La estructura es
Código
  1. typedef struct {
  2. char nombre[MAX];
  3. int renta;
  4. float nota;
  5. }lista;

Bien, si ese es el objetivo, hay un error. El problema es que cuando guardas la estructura en un archivo copiada de byte a byte, cuando copias la variable 'nombre', en realidad estás copiando la dirección de memoria donde reside el primer byte de la cadena.

Por ejemplo, declaro el siguiente objeto:

Código
  1. lista persona;
  2.  
  3. persona.nombre = "Esto es un nombre";
  4. persona.renta = 14000;
  5. persona.nota = 5;

Bien, ahora la estructura, a nivel de bits, se vería (por ejemplo), así:
Código:
0xF4567E22 // Dirección de memoria
0x000036B0 // 14000
0x00000005 // 5

Como ves, en ningún sitio aparece el nombre como tal. Entonces, lo que tendrías que hacer es primero hacer un "write" con la cadena del nombre, y luego tendrías que guardar tanto la renta como la nota en binario... Puedes usar el siguiente fragmento:

Código
  1. archivodat.write(persona.nombre, MAX);
  2. archivodat.write(reinterpret_cast<const char*>(&persona.renta), sizeof(int) + sizeof(float));


« Última modificación: 27 Enero 2016, 18:29 pm por class_OpenGL » En línea

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL
valeeen

Desconectado Desconectado

Mensajes: 46


Ver Perfil
Re: Como extraer datos de un txt y guardar en funcion de un valor en un binario??
« Respuesta #2 en: 28 Enero 2016, 09:28 am »

Gracias por la ayuda!

He introducido el código que me has dado y he comentado parte del que tenia, pero no consigo guardar en binario solo los que no superen X renta (en este caso he probado con 6000)

Código
  1. #include "Header.h"
  2.  
  3. void main()
  4. {
  5.  
  6.  
  7. lista persona;
  8. fstream archivo, archivodat;
  9. archivo.open("solicitudes.txt", ios::in);
  10. archivodat.open("agenda.dat", ios::out | ios::binary);
  11. if (!archivo) {
  12. cout << "Error al leer archivo";
  13. }
  14. else {
  15. if (!archivodat)
  16. cout << "Error creando el archivo binario";
  17. else {
  18. archivo.getline(persona.nombre, MAX, '#');
  19. archivo >> persona.renta, ' ';
  20. if (persona.renta <= '6000')
  21. {
  22. //archivo >> persona.nota;
  23. while (!archivo.eof()) {
  24. //archivo.getline(persona.nombre, MAX, '#');
  25. //archivo >> persona.renta, ' ';
  26. //archivo >> persona.nota;
  27. archivodat.write(persona.nombre, MAX);
  28. archivodat.write(reinterpret_cast<const char*>(&persona.renta), sizeof(int) + sizeof(float));
  29. //archivodat.write(reinterpret_cast<const char *>(&persona), sizeof(lista));
  30. }
  31. archivodat.close();
  32. }
  33.  
  34. }
  35. archivo.close();
  36. }
  37.  
  38. system("pause");
  39. }
  40.  

En mi txt tengo:

Pepito Perez#5000 8.1
Pepa Gonzalez#6000 5.1
Kike Alvarez#7000 9.3

Entonces debería de guardar solo los dos primeros, pero no consigo que funcione, compila pero no hace su función...

¿Como puedo hacerlo?

Muchas gracias!
En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Como extraer datos de un txt y guardar en funcion de un valor en un binario??
« Respuesta #3 en: 28 Enero 2016, 10:30 am »

Las constantes numéricas no se ponen entre comillas:
Código
  1. persona.renta <= '6000'
->
Código
  1. persona.renta <= 6000

Dices que no hace su función. Pero decir eso es no decir nada. Qué es lo que hace y qué es lo que no hace. Si preguntas de nuevo, es obvio que no hace su función.
En línea

valeeen

Desconectado Desconectado

Mensajes: 46


Ver Perfil
Re: Como extraer datos de un txt y guardar en funcion de un valor en un binario??
« Respuesta #4 en: 28 Enero 2016, 11:22 am »

Cierto, perdon jeje

Con este código ahora mismo lo que hace es leer pero nunca para, no se porque, pero se pone a escribir en binario y el archivo va creciendo pero sin sentido, solo deberia de escribir dos entradas y no para...

Código
  1. #include "Header.h"
  2.  
  3. void main()
  4. {
  5.  
  6.  
  7. lista persona;
  8. fstream archivo, archivodat;
  9. archivo.open("solicitudes.txt", ios::in);
  10. archivodat.open("agenda.dat", ios::out | ios::binary);
  11. if (!archivo) {
  12. cout << "Error al leer archivo";
  13. }
  14. else {
  15. if (!archivodat)
  16. cout << "Error creando el archivo binario";
  17. else {
  18. archivo.getline(persona.nombre, MAX, '#');
  19. archivo >> persona.renta, ' ';
  20. if (persona.renta <= 6000)
  21. {
  22. //archivo >> persona.nota;
  23. while (!archivo.eof()) {
  24. //archivo.getline(persona.nombre, MAX, '#');
  25. //archivo >> persona.renta, ' ';
  26. //archivo >> persona.nota;
  27. archivodat.write(persona.nombre, MAX);
  28. archivodat.write(reinterpret_cast<const char*>(&persona.renta), sizeof(int) + sizeof(float));
  29. //archivodat.write(reinterpret_cast<const char *>(&persona), sizeof(lista));
  30. }
  31. archivodat.close();
  32. }
  33.  
  34. }
  35. archivo.close();
  36. }
  37.  
  38. system("pause");
  39. }

No se que tengo mal (que seguro son muchas cosas)

Gracias por la ayuda

saludos
En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Como extraer datos de un txt y guardar en funcion de un valor en un binario??
« Respuesta #5 en: 28 Enero 2016, 13:38 pm »

Código
  1. while (!archivo.eof()) {
Nunca lees de archivo. Así que nunca saldrá del whiile. Tendrás que descomentar las líneas donde lees, colocar otras, o colocar otra condición.
En línea

Carlos D. Alvarez

Desconectado Desconectado

Mensajes: 5



Ver Perfil
Re: Como extraer datos de un txt y guardar en funcion de un valor en un binario??
« Respuesta #6 en: 28 Enero 2016, 16:42 pm »


Bien, ahora la estructura, a nivel de bits, se vería (por ejemplo), así:
Código:
0xF4567E22 // Dirección de memoria
0x000036B0 // 14000
0x00000005 // 5


Chicos, recuerden que si bien las cadenas de caracteres son en realidad punteros al primer caracter, cuando la cadena es estática, es almacenada en la propia estructura. En tal caso se guardaría en memoria  TAL CUAL. Si guardas la estructura, tambien se guarda la cadena, no el puntero.
En línea

Una organización y un fin
class_OpenGL


Desconectado Desconectado

Mensajes: 437

Si usas Direct3D, no eres mi amigo :P


Ver Perfil
Re: Como extraer datos de un txt y guardar en funcion de un valor en un binario??
« Respuesta #7 en: 28 Enero 2016, 21:15 pm »

Cita de: Carlos D. Alvarez
Chicos, recuerden que si bien las cadenas de caracteres son en realidad punteros al primer caracter, cuando la cadena es estática, es almacenada en la propia estructura. En tal caso se guardaría en memoria  TAL CUAL. Si guardas la estructura, tambien se guarda la cadena, no el puntero.

Pues eso no lo sabía. Para probarlo, he elaborado el siguiente código:

Código
  1. #include <iostream>
  2.  
  3. struct FOO {
  4. char lpszName[33];
  5. };
  6.  
  7. int main() {
  8. FOO foo = {"Esto es una cadena de caracteres"};
  9.  
  10. std::cout << "Size: " << sizeof(foo) << std::endl;
  11.  
  12. for(unsigned int i = 0; i < sizeof(foo); i++) {
  13. std::cout << reinterpret_cast<char*>(&foo)[i];
  14. }
  15.  
  16. std::cin.get();
  17. return 0;
  18. }

el cual imprime byte a byte toda la estructura... Lo que me ha sorprendido es obtener la siguiente salida:

Código:
Size: 33
Esto es una cadena de caracteres

Me ha sorprendido, porque no he declarado la cadena como estática, como mencionas en tu respuesta... Espero que alguien pueda aclararlo.

PD.: He usado el compilador de MinGW64 (el g++ de 64 bits para Windows).
Por si aclara algo, no he usado ninguna etiqueta al compilar (vamos, que no lo he compilado como c++11, ni nada parecido...)
En línea

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL
ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Como extraer datos de un txt y guardar en funcion de un valor en un binario??
« Respuesta #8 en: 28 Enero 2016, 21:55 pm »

Aclarado está. Como dijo Carlos, un array guarda los datos consecutivos en su memoria, en vez de guardar un puntero.

Como detalle, si inicializas un array con una constante como ahí has escrito, el compilador automáticamente copia los datos. Lo ves fácilmente si compilas el programa a ensamblador (opción -S con GCC).
La salida para:
Código
  1. int main(){
  2. char array_var[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  3. }
En mi caso, fue esta (el trozo que afecta al array):
Código
  1. movl $1145258561, 1(%esp)
  2. movl $1212630597, 5(%esp)
  3. movl $1280002633, 9(%esp)
  4. movl $1347374669, 13(%esp)
  5. movl $1414746705, 17(%esp)
  6. movl $1482118741, 21(%esp)
  7. movw $23129, 29(%esp)
  8. movb $0, 31(%esp)

Ya para finalizar, ver que, la primera asignación: "1145258561". En Hexadecimal es 44434241. Separando, se ve lo evidente: 44 43 42 41, son los caracteres DCBA.
Los penúltimos, "23129", "5A59". Y por último, el caracter nulo.

Sin embargo, si declaramos array_var como const char*, obtendremos una salida así:

Código
  1. LC0: .ascii "ABCDEFGHIJKLMNOPQRSTUVWXYZ\0"
  2. movl $LC0, 12(%esp)

Como vemos, solo copia su dirección.
En línea

class_OpenGL


Desconectado Desconectado

Mensajes: 437

Si usas Direct3D, no eres mi amigo :P


Ver Perfil
Re: Como extraer datos de un txt y guardar en funcion de un valor en un binario??
« Respuesta #9 en: 28 Enero 2016, 23:09 pm »

Interesante... ¡Cada día se aprende algo nuevo!
Por si no ha quedado claro, lo que ha dicho ivancea96 es que cuando declaramos un array dentro de una estructura (o clase), todos los datos de ese array estarán dentro de la misma (pero el array seguirá siendo un puntero, esto se explica mejor con ensamblador...), mientras que si declaramos un puntero como tal, entonces (evidentemente), los datos apuntados por ese puntero no estarán dentro de la estructura.
En línea

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines