Foros del Web » Programación para mayores de 30 ;) » C/C++ »

leer fichero con registro de variables y valores c++

Estas en el tema de leer fichero con registro de variables y valores c++ en el foro de C/C++ en Foros del Web. Hola a todos, soy nuevo en este foro y tengo conocimientos básico en c++. Lo que estoy tratando de hacer es lo siguiente: Tengo un ...
  #1 (permalink)  
Antiguo 21/11/2014, 03:26
 
Fecha de Ingreso: noviembre-2014
Mensajes: 2
Antigüedad: 9 años, 5 meses
Puntos: 0
Busqueda leer fichero con registro de variables y valores c++

Hola a todos, soy nuevo en este foro y tengo conocimientos básico en c++. Lo que estoy tratando de hacer es lo siguiente:

Tengo un archivo de texto en el cual están lineas como estas:

s123456_00045
s893264_00125
s893264_00032
s123456_00005
s112221_00452
s112221_00030
s893264_00025
s123456_00015
s112221_00001
s135133_00011

lo que quiero es generar a partir de ese un archivo como este:

s123456_00065
s893264_00182
s112221_00483
s135133_00011

es decir, en cada linea seleccionar la cadena antes del "_" como por ejemplo "s123456", ver si en la linea siguiente hay otra cadena igual y si lo hay entonces sumar su valor numérico después del guión. Para el ejemplo de arriba para "s123456" como hay otras lineas con la misma cadena, se sumaria 45+5+15 =65 por lo que la primera linea del nuevo archivo es: s123456_00065.

Se como leer el archivo, como crear el nuevo, como extraer las cadenas que necesito; pero lo que no me sale es hacer ese procedimiento de buscar los repetidos y sumar sus valores.

Unas de las cosas que estoy probando es ingresar las lineas en dos vectores y de hay realizar la operación pero no me ha funcionado el siguiente código que estaba probando.
Código:
#include <iostream>
#include <string.h>

using namespace std;

int existe(char *serie,char (*)[6]);

int main(int argc,char *argv[])
	{
	char series[8][6]={"65425","12345","12546","12345","12546","65425","98564","12546"};
	int saldos[8]={2,6,9,5,4,9,7,3};
	char *escritos[6];
	int esaldos[8];
	int ne=0;
	char cadena[6];
	//int saldo=0;
	for(int i=0;i<8;i++)
		{
		//cout<<series[i]<<" -> "<<saldos[i]<<endl;
		strcpy(cadena,series[i]);
		if(existe(series[i],escritos)==0)
			{
			for(int j=i+1;j<8;j++)
				{
				if(series[i]==series[j])
					{
					saldos[i]=saldos[i]+saldos[j];
					strcpy(escritos[ne],series[i]);
					esaldos[ne]=saldos[i];
					ne++;
					
					}
				}
			}
		}
	for(int k=0;k<ne;k++)
		cout<<escritos[k]<<" -> "<<esaldos[k]<<endl;
	return 0;
	}

int existe(char *serie,char *escrito)
	{
	for(int i=0;i<8;i++)	
		{
		if(strcmp(serie,escrito[i])==0)
			return 1;
		}
	return 0;
	}
Si hay sabe una manera de hacerlo o de hacer funcionar el código que puse arriba se los agradecería muchísimo.

Saludos.
  #2 (permalink)  
Antiguo 21/11/2014, 05:33
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: leer fichero con registro de variables y valores c++

Usa un mapa:

Código C++:
Ver original
  1. #include <iomanip>
  2. #include <iostream>
  3. #include <map>
  4.  
  5. int main( )
  6. {
  7.   std::map< std::string, int > tablaValores;
  8.  
  9.   tablaValores[ "s123456" ] += 45;
  10.   tablaValores[ "s893264" ] += 125;
  11.   tablaValores[ "s893264" ] += 32;
  12.   tablaValores[ "s123456" ] += 5;
  13.   tablaValores[ "s112221" ] += 452;
  14.   tablaValores[ "s112221" ] += 30;
  15.   tablaValores[ "s893264" ] += 25;
  16.   tablaValores[ "s123456" ] += 15;
  17.   tablaValores[ "s112221" ] += 1;
  18.   tablaValores[ "s135133" ] += 11;
  19.  
  20.   for ( auto it = tablaValores.begin( ); it != tablaValores.end( ); ++it )
  21.   {
  22.     std::cout << it->first << "_"
  23.               << std::setfill ('0') << std::setw (5) // Esto es solo para rellenar con '0'
  24.               << it->second << std::endl;
  25.   }
  26. }

Salida:

Código:
s112221_00483
s123456_00065
s135133_00011
s893264_00182
Si te fijas, el mapa ordena los resultados. Si no deseas esta característica o necesitas que los datos se impriman en el mismo orden que en la entrada.

También puedes, con un poco más de programación, hacer que el mapa ordene según el orden que tu quieres, en este caso el orden sería el de aparición de los códigos.

Para ello necesitamos asociar a cada código un index, esto lo podemos hacer con una clase tal que:

Código C++:
Ver original
  1. class Clave
  2. {
  3.   public:
  4.  
  5.     Clave( const char* codigo )
  6.       : _codigo( codigo ),
  7.         _index( GetIndex( codigo ) )
  8.     {
  9.     }
  10.  
  11.     std::string Codigo( ) const
  12.     { return _codigo; }
  13.  
  14.     int Index( ) const
  15.     { return _index; }
  16.  
  17.   private:
  18.  
  19.     static std::vector< std::string > _codigos;
  20.  
  21.     static int GetIndex( const std::string& codigo )
  22.     {
  23.       auto it = std::find( _codigos.begin( ), _codigos.end( ), codigo );
  24.       if ( it == _codigos.end( ) )
  25.       {
  26.         _codigos.push_back( codigo );
  27.         it = _codigos.end( ) - 1;
  28.       }
  29.  
  30.       return std::distance( _codigos.begin( ), it );
  31.     }
  32.  
  33.     std::string _codigo;
  34.     int _index;
  35. };
  36.  
  37. // Esta línea sirve únicamente para incializar el vector estático de códigos
  38. std::vector< std::string > Clave::_codigos;

Lo que hace básicamente es, al ingresar un código comprueba si dicho código ya tiene un índice asociado, si el índice no existe, crea uno nuevo.

Ahora necesitamos proporcionar al mapa algún mecanismo que permita ordenar los códigos en base a ese index... hay varias opciones para ello. Yo voy a optar por sobrecargar el operador de comparación:

Código C++:
Ver original
  1. bool operator<( const Clave& c1, const Clave& c2 )
  2. {
  3.   return c1.Index( ) < c2.Index( );
  4. }

Y ya tenemos todos los ingredientes necesarios. Solo nos falta actualizar la definición del mapa y listo:

Código C++:
Ver original
  1. int main( )
  2. {
  3.   std::map< Clave, int > tablaValores;
  4.  
  5.   tablaValores[ "s123456" ] += 45;
  6.   tablaValores[ "s893264" ] += 125;
  7.   tablaValores[ "s893264" ] += 32;
  8.   tablaValores[ "s123456" ] += 5;
  9.   tablaValores[ "s112221" ] += 452;
  10.   tablaValores[ "s112221" ] += 30;
  11.   tablaValores[ "s893264" ] += 25;
  12.   tablaValores[ "s123456" ] += 15;
  13.   tablaValores[ "s112221" ] += 1;
  14.   tablaValores[ "s135133" ] += 11;
  15.  
  16.   for ( auto it = tablaValores.begin( ); it != tablaValores.end( ); ++it )
  17.   {
  18.     std::cout << it->first << "_"
  19.               << std::setfill ('0') << std::setw (5) // Esto es solo para rellenar con '0'
  20.               << it->second.Codigo( ) << std::endl;
  21.   }
  22. }

Salida:

Código:
s123456_00065
s893264_00182
s112221_00483
s135133_00011
  #3 (permalink)  
Antiguo 31/12/2014, 00:19
 
Fecha de Ingreso: noviembre-2014
Mensajes: 2
Antigüedad: 9 años, 5 meses
Puntos: 0
Respuesta: leer fichero con registro de variables y valores c++

hola eferion gracias por tu respuesta, esos de los mapas se ve muy bueno... para un archivo de texto con mas de 40 millones de lineas, se podrá usar mapas? o que otra cosa se podría probar?


El código que realicé arriba me funciona pero para pocos datos, para archivos con más de 40 millones de líneas no me funciona porque el vector que tendría que usar sería demasiado grande y no me soporta la memoria.

Saludos

Última edición por b0rya0n; 31/12/2014 a las 00:50

Etiquetas: char, fichero, funcion, int, registro, variables
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:58.