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

Problema entrada datos (novato)

Estas en el tema de Problema entrada datos (novato) en el foro de C/C++ en Foros del Web. Hola amigos. Verán soy neófito en c++ y tengo un problemilla relativamente sencillo. Dispongo de un archivo de datos que contiene 2000 lineas y cada ...
  #1 (permalink)  
Antiguo 16/02/2013, 08:22
 
Fecha de Ingreso: febrero-2013
Mensajes: 6
Antigüedad: 11 años, 3 meses
Puntos: 0
Problema entrada datos (novato)

Hola amigos.

Verán soy neófito en c++ y tengo un problemilla relativamente sencillo. Dispongo de un archivo de datos que contiene 2000 lineas y cada una de ellas un nummero entero y un real con dos decimales. Es dicir tiene la siguiente forma:

12 123.1
121 43.24
1 23.1

Me gustaría leer el texto fila a fila y almacenar la primera columna en un vecor dosmildimensional de enteros, i, y la segunda en un vector dos mil dimensional x.

Como puedo hacerlo, estoy leyendome cositas sobre void, pero no consigo resolverlo. Ayuda por favor.

Fracias por adelantarlo, me da verguenza tener que pedir ayuda con unm problema tan sencillo.
  #2 (permalink)  
Antiguo 16/02/2013, 09:19
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 9 meses
Puntos: 83
Respuesta: Problema entrada datos (novato)

"...Fracias por adelantarlo..."

Ante todo mucha calma :)


Un vector dosmildimensional de enteros en principio no sera necesario, con solo un vector de dosmil elementos unidimensional tienes mas que suficiente. Otra cosa: quieres usar vectores de c++ o listas de tipos?

Código:
//con vectores, requiere la cabecera vector
vector <int> vector_lista_de_enteros;

//la otra forma
int lista_de_enteros[2000];
Ahora lo que mas te interesa: lleer el archivo. Si sabes que siempre (siempre quiere decir que siempre) los datos del archivo seran entero-espacio-flotante puedes leer directamente del puntero al archivo

Código:
//declaras las variables de destino
int entero;
float flotante;

//abres el archivo para lectura, requiere fstream
ifstream archivo("test.txt");

//vas leyendo con el tokenizador de espacios que viene por defecto
while (archivo >> entero >> flotante) {
    ...
}
Dentro del bucle ya tienes los valores tokenizados, en cada ciclo los correspondientes a la linea. Lo unico que te queda es rellenar las listas, si usas los vectores haces un push_back y solucionado, si usas listas de tipos simplemente guardas un contador incremental (un simple int que se incrementa a cada ciclo) para acceder a la posicion y asignas el dato, tranqui que es muy simple:

Código:
//con vectores
vector_lista_de_enteros.push_back(entero);

//con lo otro
lista_de_enteros[indice] = entero;
Una cosa, tal vez te interese hacer listas de estructuras donde puedes guardar ambos datos en un mismo 'nodo' en vez de tener los enteros en una lista y los flotantes en otra, ten presente que esta es otra opcion.

Saludos
vosk
  #3 (permalink)  
Antiguo 16/02/2013, 10:53
 
Fecha de Ingreso: febrero-2013
Mensajes: 6
Antigüedad: 11 años, 3 meses
Puntos: 0
Respuesta: Problema entrada datos (novato)

Gracias voosk por responder. Lo siguiente funciona perfectamente.

#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <ctype.h>
using namespace std;




int main ()
{
//declaración de variables

int y[2881];
double x[2881];
int i=0;

//apertura y lectura archivo
ifstream archivo("yx.txt");

if (archivo.is_open()) {
while (archivo.good()){
i++;
archivo>>y[i]>>x[i];

}
archivo.close();
}
else cout << "no se puedo abrir el archivo";

for (i=0;i<2881;i++)
cout<<i+1<<" "<<y[i]<< " "<<x[i]<<"\n";


system ("pause");
return 0;
}


Como puedo mejorar?Quizás usando punteros.

Última edición por pibi; 16/02/2013 a las 11:26
  #4 (permalink)  
Antiguo 16/02/2013, 11:57
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 9 meses
Puntos: 83
Respuesta: Problema entrada datos (novato)

Antes de nada, quita la cebecera conio porque no es estandar y usa getchar() en vez de system("pause"), quita tambien todas las cabeceras que no vayas a usar (en este caso y solo por lo que tienes en el codigo puedes usar solamente iostream y fstream), y como ultimo indenta el codigo; con esto no mejoras el proceso pero lo 'maquillas' a nivel de codigo.

Puedes probar a plantear el flujo de datos de otras formas: en vez de declarar una array de 2881 elementos puedes usar algo de memoria dinamica para expandir un contenedor, o crear listas enlazadas, o usar vectores. En c++ se recomienda usar los contenedores stl en vez de usar tus propios manejadores de memoria (aunque tambien puedes hacerlo, pero te será mas complejo). Con vectores y structs es facil:

Código:
typedef struct {
    int entero;
    float flotante;
} PAR;

vector <PAR> v_pares;
vector <PAR>::iterator itr;
PAR par;

//me salto lo de abrir archivo y comprovaciones de error
while (archivo.good()) {
    archivo >> par.entero >> par.flotante;
    v_pares.push_back(par);
}

//vuelcas los datos con un iterador
for(itr = v_pares.begin(); itr < v_pares.end(); itr++) {
    cout << (*itr).entero << ", " << (*itr).flotante << endl;
}

//tambien puedes acceder a los elementos del vector como si fuese un array
for(int q = 0; q < v_pares.size(); q++) {
    cout << v_pares[q].entero << ", " << v_pares[q].flotante << endl;
}

//liberas el vector
v_pares.clear();
De esta forma puedes cargar todo el archivo sin preocuparte por el numero de elementos que guardas.

Saludos
vosk
  #5 (permalink)  
Antiguo 16/02/2013, 18:01
 
Fecha de Ingreso: febrero-2013
Mensajes: 6
Antigüedad: 11 años, 3 meses
Puntos: 0
Respuesta: Problema entrada datos (novato)

Gracias por tus consejos, no me hizo falta usar estructuras para resolver el problema, pero le echaré un vistazo para mejorar la eficacia. Estoy acostumbrado a programar en otros lenguajes pero en c soy neófito y hay cosas muy sencillas que aún no sé hacer, pero poco a poco ire mejorando.

Un saludo, como puedo hacer para ponerte algún punto?
  #6 (permalink)  
Antiguo 17/02/2013, 07:57
 
Fecha de Ingreso: febrero-2013
Mensajes: 6
Antigüedad: 11 años, 3 meses
Puntos: 0
Respuesta: Problema entrada datos (novato)

He hecho el código del programa sin problemas. Ahora me propongo a una mejora del programas. Tengo dos archivos de datos, que tiene la siguiente estructura:

El primero de ellos (observaciones.txt) tiene 2881 con la siguiente estructura fecha hora producion velocidad, por ejemplo:

2010-03-01 23:00 34 45.21
2010-03-02 02:00 21 12.14

como hago para leerlo usando estructuras. ¿Qué hago mal en este fragmento de código?

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main ()
{

struct observacion{ //estructura observacion
char fecha[15];
char hora[7];
int producion;
float velocidad;
}ob[2881];

struct predicion{ //estrucura produción

}pro[9];


//declaracion variables
int i;

//abrimos archivo
ifstream archivo("observaciones.txt");


if (archivo.is_open()) { //leemos archivo
while (archivo.good()){
i++;
archivo>>ob[i].fecha>>ob[i].hora>>ob[i].producion>>ob[i].velocidad;
}
archivo.close();
}

else cout << "no se puedo abrir el archivo";


getchar();
return 0;
}
  #7 (permalink)  
Antiguo 17/02/2013, 09:16
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 9 meses
Puntos: 83
Respuesta: Problema entrada datos (novato)

El primer indice de una lista es el 0, en el codigo estas declarando un incremental 'i' que para cada ciclo lo incrementas y luego lo usas como indice; el error está en que vas referenciando un elemento bajo un indice que está una posicion adelante de lo que tendria que estar, de forma que cuando llegas a la ultima lectura asignas los datos a un struct para el que no has guardado memoria (en la ultima lectura 'i' vale 2881, pero como el indexado comienza en 0, la posicion 2881 es en realidad el elemento 2882 para el que no has reservado memoria ok? )

Código:
i = 0;
while(archivo.good()) {
    archivo >> ob[i].fecha >> ob[i].hora >> ob[i].producion >> ob[i].velocidad;
    i++;
}

Algo mas, evita el hardcoded de datos:

Código:
struct observacion {
    char fecha[15];//aqui
    char hora[7];//aqui
    int producion;
    float velocidad;
} ob[2881];//y aqui
Para eso tienes que declarar otra cabecera con las definiciones para las longitudes y otros tipos de datos que vas a usar en la aplicacion, de forma que si necesitas modificar algo que has usado x veces por dentro del codigo solo necesitaras tocar el archivo de definiciones en vez de recorrer todo el codigo buscando y cambiando. Y lo del 'ob[2881]', si quieres usar este tipo de array entonces tendras que añadir un condicional dentro del ciclo de lectura para evitar que lea mas lineas de las que caben en el array: esto es un parche, no una forma correcta de solucionarlo; para solucionarlo tienes que usar vectores o listas.

Saludos
vosk
  #8 (permalink)  
Antiguo 17/02/2013, 09:16
 
Fecha de Ingreso: febrero-2013
Mensajes: 6
Antigüedad: 11 años, 3 meses
Puntos: 0
Respuesta: Problema entrada datos (novato)

#include <iostream>
#include <fstream>
#include <string.h>
#include <stdio.h>

using namespace std;

struct observacion{ //estructura observacion
char fecha[11];
char hora[6];
int producion;
float velocidad;
};



int main ()
{

//declaracion variables
int i;
struct observacion ob;
char auxfecha[11]="01-05-2009";
char auxhora[6]="15:00";

strcpy(ob.fecha,auxfecha);
strcpy(ob.hora,auxhora);

ob.producion=12;
ob.velocidad=12.98;

printf("El día %s a las %s hubo una producion de %d . el modululod de la velcidad fue %f",ob.fecha,ob.hora,ob.producion,ob.velocidad);

getchar();
return 0;
}


Bueno, la estructura funciona y se improme bien, ahora el priblema será en conseguir la lectura del fichero.
  #9 (permalink)  
Antiguo 17/02/2013, 10:55
 
Fecha de Ingreso: febrero-2013
Mensajes: 6
Antigüedad: 11 años, 3 meses
Puntos: 0
Respuesta: Problema entrada datos (novato)

Yo sigo acercandome a la solucion final a los problemas de entrada de datos, pero aún hay algo que fallar, hasta ahora tengo el siguiente codigo pero no se muy bien porque la dunción de imprimir no funciona. Mi objetivo es leer las 2881 lineas del archivo, a ver si poco a poco lo damos hecho.

#include <iostream>
#include <fstream>
#include <string.h>
#include <stdio.h>

using namespace std;

typedef struct obs{ //estructura observacion
char fecha[11];
char hora[6];
int producion;
float velocidad;
}obs_t;

//funcion crear observacion
obs_t crear_obs(){
//creo la nueva observacion en blanco
obs_t nueva_observacion;
//asigno fecha
printf("Ingrese la fecha de la observacion ");
fflush(stdin);
gets(nueva_observacion.fecha);
//asigno hora
printf("Ingrese la hora de la observacion ");
fflush(stdin);
gets(nueva_observacion.hora);
//asigno producion
printf("Ingrese la producion: ");
fflush(stdin);
scanf ("%d",nueva_observacion.producion);
//asigno velocidad
printf("Ingrese el modulo de la velocidad: ");
fflush(stdin);
scanf ("%2.f",nueva_observacion.velocidad);
//devuelvo nueva obsercacion
return nueva_observacion;
}

//funcion para imprimir una observacion
void imprimir_obs(obs_t obs){
printf("%s,%s,%f,2.f\n",obs.fecha,obs.hora,obs.pro ducion,obs.velocidad);
}

int main (void)
{
obs_t obs1=crear_obs();
obs_t obs2=crear_obs();
imprimir_obs(obs1);
imprimir_obs(obs2);

return 0;
}
  #10 (permalink)  
Antiguo 17/02/2013, 12:55
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 9 meses
Puntos: 83
Respuesta: Problema entrada datos (novato)

Creo que deberias echar otro vistazo a tu manual de c++.

La funcion scanf espera una cadena de formato y en caso necesario una lista de referencias a variables de destino; estas variables de destino deben ser del tipo acorde a los especificadores de formato que indicas en la cadena de formato

Código:
char palabra[10];
scanf("%s", palabra);

int entero;
scanf("%d", &entero);

float flotante;
scanf("%f", &flotante);

int lista_enteros[10];
scanf("%d", &lista_enteros[2]);

int *entero_dinamico;
entero_dinamico = new int;
scanf("%d", entero_dinamico);
delete entero_dinamico;

int *lista_enteros_dinamicos;
lista_enteros_dinamicos = new int[10];
scanf("%d", &lista_enteros_dinamicos[2]);
delete [] lista_enteros_dinamicos;
El '&' significa referencia, y es un puntero al bloque de memoria que ocupa esa variable. Si envias la variable desreferenciada realmente estas enviando el valor como 'solo lectura', la otra funcion puede mostrarlo y modificarlo pero solo en el scope de esa funcion. En los casos de texto no es necesario enviar la referencia porque la propia variable ya es una referencia; igual sucede si usas memoria dinamica de un solo elemento pero no si creas dinamicamente una lista de elementos porque la variable es un puntero a la lista de elementos pero cada elemento necesita ser referenciado.


Aun tienes otra cosa en el scanf y en el printf, el especificador de formato que usas no existe.

Saludos
vosk
  #11 (permalink)  
Antiguo 24/02/2013, 13:29
 
Fecha de Ingreso: febrero-2013
Mensajes: 3
Antigüedad: 11 años, 3 meses
Puntos: 0
Respuesta: Problema entrada datos (novato)

alguien que ayude http://www.forosdelweb.com/f96/tarea-c-1039027/

Etiquetas: entrada, vectores
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 09:59.