duda vector y class

LioNHearT

buenas tardes. tengo la siguiente duda: dispongo de un vector de tipo Trucada (class), en el cual ire guardando los datos de un fichero. cada linea del fichero sera una posicion del vector, tal que asi:

class Trucada{
public:
char estat;
string data;
string hora;
int ext;
string nom;

vector <Trucada> V;
Trucada T;
cin >> x (supongamos que este sea el bucle de lectura del archivo)
(ahora lo guardamos en el vector)

V[k].T.estat=x;

lo que quiero es saber es como hacer eso:
V[k].T.estat=x;

ya que el compilador no me deja acceder asi a los valores de la class en esa posicion del vector.

creo que mas o menos lo he explicado bien... xD. alguien me hecha una mano plis?

muchas gracias ;)

cabron

Cada elemento del vector es un objeto de la clase (supniendo que hayas guardado un objeto en esa posición claro):

Vector <MiClase> listaObjetos.

listaObjetos[2].miPropiedad = 4; //Suponiendo que en la posición 2 haya metido un objeto antes

lo que tu haces de:

listaObjetos[2].miObjeto.miPropiedad

no tiene sentido.

LioNHearT

vale es como me suponia. entonces porque pensais que al hacer este bucle me peta el programa?

 ifstream ficheroTel;
 ficheroTel.open("tel1pet.txt");
 ficheroTel >> x;
 cout << "Hola" << endl;
 while (!ficheroTel.eof()){
        trucades[k].estat=x;
        ficheroTel >> y;
        trucades[k].data=y;
        ficheroTel >> y;
        trucades[k].hora=y;
        ficheroTel >> x;
        trucades[k].ext=x;
        ficheroTel >> y;
        trucades[k].nom=y;
        k++; 
 
 ficheroTel >> x;
 }

el fichero a leer tiene la siguiente estructura:

  • 2008/20/11 00:00:15 82 groucho
  • 2008/20/11 00:00:31 84 harpo
  • 2008/20/11 00:00:41 84 chico
  • 2008/20/11 00:27:18 84 chico
  • 2008/20/11 01:10:27 82 groucho

osea ago un cin de cada valor. el problema creo que está con los espais, ya que al leer un string me cogera el espacio. puede ser?

entonces, dado un string, como hago para omitir un espacio y que lea el siguiente caracter?

LioNHearT

bueno he hecho lo siguiente:
while (!ficheroTel.eof()){
trucades[k].estat=x;
ficheroTel >> y;
if (y==" ") ficheroTel >> y;
trucades[k].data=y;
ficheroTel >> y;
if (y==" ") ficheroTel >> y;
trucades[k].hora=y;
ficheroTel >> x;
trucades[k].ext=x;
ficheroTel >> y;
if (y==" ") ficheroTel >> y;
trucades[k].nom=y;
k++;


 ficheroTel >> x;
 }

realizo el mismo bucle y, cuando llegue a un string, si es un espacio vovler a omitirlo. pero sigue dandome error. se os ocurre alguna cosa?

dagavi

Es que no estaría de más que pusieras todo el código, aunque el error se pudiera ver desde el cacho que has puesto.

Igualmente algunos cambios que yo haría:
Cabe la posibilidad de que tu programa pete si no hay entrada ya que haces directamente "cin >> x", y para la estrucutra que tienes yo te recomentaría mejor en vez de hacer:

(lo expresaré sobre cin aunk es lo mismo para archivos)

cin >> x;
while (not fin archivo) { .....; cin >> x; }

Hacer:
while (cin >> x) {
....
}

Por otro lado, pero esto ya es por gusto mio, si estás leyendo una variable pues yo lo leería directamente, es decir, en vez de hacerlo en dos pasos:
cin >> s;
v[k].algo = s;

pues directamente cin >> v[k].algo;

Algo raro es que, sin decirnos ni los tipos, haces:
ficheroTel >> x; (3º línea)

Teniendo en cuenta que lo primero que se ve en la muestra que pones es un carácter deberé suponer que x es un char, ya que además lo copias en estat que es un char.

Al final haces:
ficheroTel >> x;
trucades[k].ext=x;

Pero ahí estás leyendo un char cuando en verdad deberías leer un número (82 en el primer ejemplo) y asignas el char a un int, que es trucades[k].ext. Si el problema es esto, que te has equivocado en este punto, se te hubiera arreglado directamente si no usaras variables intermedias y leyeras directamente sobre la variable final.

La lectura de datos, es decir todo el bucle, diría que lo puedes resumir en una simple línea:
while (ficheroTel >> trucades[k].estat >> trucades[k].data >> trucades[k].hora >> trucades[k].ext >> trucades[k].nom);

LioNHearT

te pongo todo el codigo:

#include <cstdlib>
#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include "Trucada.hpp"
using namespace std;

int main(){


 char x;
 int k=0;
 string y;
 Trucada T;
 vector <Trucada> trucades; 
 ifstream ficheroTel;
 ficheroTel.open("tel1pet.txt");
 cout << "PROBA" << endl;
 while (ficheroTel >> x || ficheroTel >> y){
        ficheroTel >> trucades[k].estat;
        ficheroTel >> y;
        if (y==" ") ficheroTel >> trucades[k].data;
        ficheroTel >> y;
        if (y==" ") ficheroTel >> trucades[k].hora;
        ficheroTel >> x;
        trucades[k].ext=x;
        ficheroTel >> y;
        if (y==" ") ficheroTel >> trucades[k].nom;
        k++; 
 
 ficheroTel >> x;
 }
 ficheroTel.close();

he simplificado las 2 primeras cosas que me has comentado, dejando los ficheroTel >> y, para ignorar los espacios, ya que no se me ocurre otra manera de hacerlo.

el problema que veo en la manera que me pones de leer todo el archuivo en 1 sola linea, esta en que no todo lo que quiero leer es lo mismo. es decir, que lo que leere (en cada linea), segun este orden es:

char
string
string
int
string
por eso creo que no puedo hacerlo asi. que opinas? o mejo dicho, que podria hacer para que cuando lea:

  • 2008/20/11

1º me guarde el char (+), despues ignore el espacio y por ultimo guarde el string (2008/20/11) ???

gracias por la ayuda.

maRc

Ponlo con entre [ code] [/ code], que se verá mejor. Y si mantienes la indentación, todavía más.

LioNHearT

te pongo todo el codigo:

#include <cstdlib>
#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include "Trucada.hpp"
using namespace std;

int main(){

char x;
int k=0;
string y;
Trucada T;
vector <Trucada> trucades;
ifstream ficheroTel;
ficheroTel.open("tel1pet.txt");
cout << "PROBA" << endl;
while (ficheroTel >> x || ficheroTel >> y){
ficheroTel >> trucades[k].estat;
ficheroTel >> y;
if (y==" ") ficheroTel >> trucades[k].data;
ficheroTel >> y;
if (y==" ") ficheroTel >> trucades[k].hora;
ficheroTel >> x;
trucades[k].ext=x;
ficheroTel >> y;
if (y==" ") ficheroTel >> trucades[k].nom;
k++;

ficheroTel >> x;
}
ficheroTel.close();

he simplificado las 2 primeras cosas que me has comentado, dejando los ficheroTel >> y, para ignorar los espacios, ya que no se me ocurre otra manera de hacerlo.

el problema que veo en la manera que me pones de leer todo el archuivo en 1 sola linea, esta en que no todo lo que quiero leer es lo mismo. es decir, que lo que leere (en cada linea), segun este orden es:

char
string
string
int
string
por eso creo que no puedo hacerlo asi. que opinas? o mejo dicho, que podria hacer para que cuando lea:

  • 2008/20/11

1º me guarde el char (+), despues ignore el espacio y por ultimo guarde el string (2008/20/11) ???

gracias por la ayuda.

dagavi

La IOS de C++ ya te ignora, usándolo de esta forma, los espacios, es decir si lees:

3          3

es lo mismo que

3 3

Pero no es lo mismo que
33 (que leería 33, o 2 carácteres 3 si lees un char)

Igualmente la notación de la IOS se encarga de guardar cada cosa según el tipo de la variable que le pasas, es decir, perfectamente puedes leer:
int string int

Para que lo veas he copiado lo que has puesto de la clase y he hecho un sencillo main que lee un objeto de tipo trucada y escribe el contenido de los campos.

http://pastebin.com/m2b4f0c0a

Como ves no hay problema alguno en leer distintos tipos de golpe.

Por otro lado, es también normal que te pete, creas un vector sin contenido e intentas meterle cosas, eso está mal.

vector <Trucada> trucades;
cin >> trucades[k].algo

En trucades[k] no hay nada, no existe esa posición del vector. Debes especificar el tamaño, pero no lo sabes, así que debes usar push_back. Es decir, crearemos un vector de 0 elementos e iremos añadiendo elementos. (edit: si no pones el tamaño también funciona ya que por defecto se crea de tamaño 0, pero igualmente la posición k no existe, debes de ir metiendo los elementos)

Meterlo en un vector es muy sencillo, aquí te dejo una variante de mi main que lo leerá y te lo dejará en un vector:

http://pastebin.com/m4ccf47a6

LioNHearT

vale, la manera de leer el vector la entiend. lo que una dudao, el while de lectura, no habria otra manera de hacerlo mas corto? diciendolo que lo hafa hasta que llegue al final del archivo o algo? es que dado mi programa es el doble de condiciones que tiene (osea el doble de las que tu as puesto)

gracias tiuuu

LioNHearT

bueno he probado a hacerlo como tu me dices y me da muchos errores. esto he hecho:

     char x;
     int k=0, l=0;
     string y;
     Trucada T;
     vector <Trucada> trucades_in;
     vector <Trucada> trucades_fi;
     ifstream ficheroTel;
     ficheroTel.open("tel1pet.txt");
     cout << "PROBA" << endl;
     //lectura archivo
     ficheroTel >> x;
     while (ficheroTel >> trucades_in.data >> trucades_in.hora >> trucades_in.ext >> trucades_in.nom
     || ficheroTel >> trucades_fi.data >> trucades_fi.hora >> trucades_fi.ext >> trucades_fi.nom){

       if (ficheroTel == '+') trucades_in.push_back(T);
       if (ficheroTel == '-') trucades_fi.push_back(T);
        }

ya nose como guardarlo tio, me estoy volviendo loko xDDD. dime algo pliss :$:$:$

LioNHearT

bueno he hecho la siguiente modicicacion pero me sigue dando error:

     char x;
     int k=0, l=0;
     string y;
     Trucada T;
     vector <Trucada> trucades_in;
     vector <Trucada> trucades_fi;
     ifstream ficheroTel;
     ficheroTel.open("tel1pet.txt");
     cout << "PROBA" << endl;
     //lectura archivo
     ficheroTel >> x;
     while (ficheroTel >> x || ficheroTel >> y){

        if (x == '+'){
       ficheroTel >> y; T.data=y;
       ficheroTel >> y; T.hora=y;
       ficheroTel >> x; T.ext=x;
       ficheroTel >> y; T.nom=y;
       trucades_in.push_back(T);
       }
       if (x == '-'){
       ficheroTel >> y; T.data=y;
       ficheroTel >> y; T.hora=y;
       ficheroTel >> x; T.ext=x;
       ficheroTel >> y; T.nom=y;
       trucades_fi.push_back(T);
       }
 }
 ficheroTel.close();

que puede fallar?

dagavi

Deberías repasar los conceptos de las cosas porque lo que acabas de escribir es una orgía de burradas xD (edit: aunque veo que han desaparecido en el el 2º post que has puesto xD)

if (ficheroTel == '+') trucades_in.push_back(T);
if (ficheroTel == '-') trucades_fi.push_back(T);

ficheroTel es una instancia de ifstream. ¿como y para que lo comparas conun char?
Tu lo que quieres ver si es '+' o '-' es trucada.estat


ficheroTel >> trucades_in.data >> trucades_in.hora

¿Te das cuenta de lo que estás haciendo ahí? Estás intentando escribir sobre un objeto vector! no trucades_in no es una Trucada, es un putu vector. trucades_in[x] SI es una trucada.


El || (aunque yo lo escribiría directamente en palabras, queda más C++ xD es decir "or") no tiene sentido y no lo puedes usar, es más intentará leer e primer carácter un "+" y meterlo en el entero y el programa petará.

Debes de pensar la lectura como secuencial y sin vuelta atrás es decir, no pienses "intento leer esto y si no lo otro".

Viendo que quieres separarlo en 2 vectores sería tan sencillo como:
http://pastebin.com/d3815e798

Y si no te interesa (ya que he visto que has vuelto a responder) el estat, simplemente lo quieres leer una vez, pues se puede quitar fácilmente:
http://pastebin.com/m2390fd98

LioNHearT

vale, creo que de momento funciona. ahora me surge otra duda (que pensaba que lo tenia bien). ahora quiero ordenar los 2 vectores creados a partir del valor T.ext. he hecho este bucle (el mismo para los 2 vectores):

int i, j, flag = 1; 
	vector <Trucada> copia; 
	for(i = 1; (i <= trucades_in.size()) && flag; i++){
		flag = 0;
		for (j=0; j < (trucades_in.size() -1); j++){
			if (trucades_in[j+1].ext < trucades_in[j].ext){ 
				copia[0] = trucades_in[j]; 
				trucades_in[j] = trucades_in[j+1];
				trucades_in[j+1] = copia[0];
            }
              }
             }

creo que es aki donde me peta. utilizo el metodo de la burbuja, y mediante un vector copia, ordeno el vector de menor a mayor ext. que falla?

Dod-Evers

Joer, ya es jodido cuando la programacion es mezclando inglés i castellano/español,... si ya me metes catalan... no pensáis que cuando trabajéis puede haber gente que no hable catalán (ni español) e incluso que podéis ir a trabajar al extranjero!!!

Ains...

dagavi

Volvemos a lo mismo:

vector <Trucada> copia;
copia[0] = trucades_in[j];

copia[0] no existe

Puedes solucionarlo, aunque no lo hagas, creando el vector con 1 elemento: vector<Trucada> copia(1)

Pero es obvio que no debes usar un vector para almacenar 1 trucada, crea una instancia de trucada y listo. También veo que usas una cosa que le llamas "flag" lo pones a 0, no lo vuelves a tocar y encima pones "for ... flag .." es decir, estás condenando el bucle a que solo haga una iteración ya que nunca lo pones a != 0, finalmente si estás programando en C++ usa el boolean (bool), que para eso está.

También llegas hasta vector.size() con <= otro error, vector.size() retorna el tamaño del vector, pero la última posición de este es una menos (ya que empieza por 0) es decir siempre te debes de quedar en vector.size() - 1, lo que se suele programar "for (int i = 0; i < vector.size(); ++i)" (sin el = del <=)

Y si lo vas a hacer a más de un vector no debes de copiar y pegar el código, si no crear funciones y acciones, en este caso una que sea, por ejemplo, "ordena":

http://pastebin.com/m39ed28b5

(para hacer un intercambio se puede usar directamente swap(a, b))

LioNHearT

ya se que tengo que usar funciones, pero sinceramente, me lio a la hora de usarlas tio :$:$. porque nunca se si tengo que ponerlas arriba del todo o a donde... me hechas una mano :$?

y mira, lo ultimo (creo que lo mas complicado xD). debo mostrar los resultados con el siguiente eskema:

Ext 44:
admin 2008/20/11[00:00:26--00:52:58]
Ext 55:
montse 2008/20/11[00:00:44--01:17:28]
Ext 56:
montse 2008/20/11[12:28:16--12:29:29]
Ext 69:
admin 2008/20/11[18:36:18--18:58:24]
montse 2008/20/11[02:12:47--02:19:36]
Ext 83:
montse 2008/20/11[02:28:20--02:32:02]

entonces, para ver los tiempos, lo que habia pensado es, hacer un if que compare la ext de los 2, si coincide, lo muestra, y sino, busco en la siguiente posicion. algo asi:

l=0;
for (k=0 ; k<5 ; k++){
cout << endl << "Ext " << trucades_in[k].ext << ":" << endl;
cout << "    " << trucades_in[k].nom << " "<< trucades_in[k].data << "[";
while (trucades_in.ext[l] != trucades_fi.ext[l]){
      if(trucades_in.ext[l] == trucades_fi.ext[l])
   cout << trucades_in[k].hora << "--" << trucades_fi[k].hora << "]" << endl;
   else l++;
}
k++;
}

que se te ocurre?

(y perdona por abusarrr :$ )

dagavi

Las funciones simplemente se han de declarar antes de ser usadas, no tiene mayor misterio, es decir, simplificando, puedes ponerlo siempre arriba del main. (obviamente si una función A usa una función B, pues B deberá estar encima de A).

Respecto a la salida no se me ocurre nada ya que representa esa salida ni como usar los vectores in y fin, más teniendo en cuenta que más de 1 llamada puede tener la misma ext.

LioNHearT

bueno al final si use funcion, probé y listo (sabia que era como decias, pero una vez tube problemas con funciones y me rayé xD). respecto a lo de ordenar lo que te he dicho, es un for dentro de otro for, lo que pasa que es bastante complejo. si consigo sacarlo lo pongo aki.

1000 gracias!!!

Usuarios habituales

  • LioNHearT
  • dagavi
  • Dod-Evers
  • maRc
  • cabron