0

So I made that code, it get a in file for reading, read it into a temporary variable of a object then push_back it to a vector as container. But... its not working, after the last one, all variables get the information of the last one object read in file!

setObject class:

template <typename Objeto, typename Container>
void setObjetos(const string& nome, Container& objetos){
    ifstream in (nome.c_str());
    Objeto temporario;
    while(in >> temporario){
        cout << "temporario: " << temporario << endl;
        objetos.push_back(temporario);
        cout << "Objetos.front():" << objetos.front() << endl;
        cout << "Objetos.back():" << objetos.back() << endl;
    }
    in.close();
    for (auto it : objetos) {
        cout << "Objeto it em set apos while: "<< endl << it;
    }
}

then, i got that class that calls it, for exemple: that class receive an object to a verify, then, I get the container of objects from "SetObjectos" and do some comparing:

template <typename Objeto>
template <typename Objeto, typename Container>
int verifica(Objeto objeto, const string& nome){
    existe(nome);
    Container objetos;
    setObjetos<Objeto, Container>(nome, objetos);
    for (auto it : objetos) {
        cout << "Objeto it: "<< endl << it;
        if (strcmp(it.getChave(), objeto.getChave()) == 0){
            return 1;
        }
    }
    return 0;
}

that's how I am calling up that verifica function, for exemple, in a login situation:

void Clinica::login(const string& arquivo)
    {
        char* usuario = new char[12];
        char* senha = new char[12];
        cout << endl << "INSIRA O USUARIO: ";
        cin >> usuario;
        cout << endl << "INSIRA A SENHA: ";
        cin >> senha;
        Usuario user(usuario, senha, '0');
        user.setChave();
        if (!verifica<Usuario, vector<Usuario>>(user, arquivo)){
            cout << endl << "USUARIO OU SENHA INVALIDOS!" << endl;
        }else{
            Usuario temp = getObjeto<Usuario>(user, arquivo);
            if (strcmp(temp.getSenha(), user.getSenha()) == 0){
                user = temp;
                temp.~Usuario();
                switch (user.getTipo()) {
                    case 'A':
                        this->menuAdministrador(user);
                    break;

                    case 'B':
                        this->menuAssistenteAdministrativo(user);
                    break;

                    case 'G':
                        this->menuUsuarioGeral(user);
                    break;
                }
            }else{
                cout << endl << "USUARIO OU SENHA INVALIDOS!" << endl;
            }
        }
    }

and then, that is my user object:

#include "usuario.hpp"

        Usuario::Usuario(){}

        Usuario::Usuario(const char usuario[12], const char senha[12], const char& tipo):
        usuario((char*)usuario), senha((char*)senha), tipo(tipo){}

        Usuario::~Usuario(){}

        void Usuario::setUsuario(const char usuario[12]){
            this->usuario = (char*)usuario;
        }

        void Usuario::setSenha(const char senha[12]){
            this->senha = (char*)senha;
        }

        void Usuario::setTipo(const char tipo){
            this->tipo = tipo;
        }

        char* Usuario::getUsuario(){
            return this->usuario;
        }

        char* Usuario::getSenha(){
            return this->senha;
        }

        char Usuario::getTipo(){
            return this->tipo;
        }

        void Usuario::setChave(char* chave){
            this->chave.setChave( chave );
        }

        void Usuario::setChave(){
            this->chave.setChave( usuario );
        }

        char* Usuario::getChave(){
            return this->chave.getChave();
        }

        ostream& operator <<(ostream& out, const Usuario& user){
            out << user.chave << "\n" << user.usuario << "\n" << user.senha << "\n" << user.tipo << endl;
            return out;
        }

        istream& operator >>(istream& in, Usuario& user){
            in >> user.chave;
            in >> user.usuario; 
            in >> user.senha; 
            in >> user.tipo;
            return in;
        }

which get a public uhhh I realy dont know the name in english of that, we call that herança in portugue, and java its like extends... but I guess you guys know what i mean... well User extends from Chave, that is a unique key that every class have so when I want to do some comparing and stuff in my template class:

#include "chave.hpp"

Chave::Chave(){}

Chave::~Chave(){}

void Chave::setChave(char* chave){
  this->chave = chave;
}

char* Chave::getChave(){
  return this->chave;
}

ostream& operator<<(ostream& out, const Chave& chave){
  out << chave.chave;
  return out;
}

istream& operator>>(istream& in, Chave& chave){
  in >> chave.chave;
  return in;
}

Sample output of code:

temporario: admin
admin
admin
A

Objetos.front():admin
admin
admin
A

Objetos.back():admin
admin
admin
A

temporario: teste
teste
testando
G

Objetos.front():teste
teste
testando
A

Objetos.back():teste
teste
testando
G

temporario: 1'244
1'244
134223
G

Objetos.front():1'244
1'244
134223
A

Objetos.back():1'244
1'244
134223
G

temporario: 43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G

Objetos.front():43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
A

Objetos.back():43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G

Objeto it em set apos while: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
A
Objeto it em set apos while: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G
Objeto it em set apos while: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G
Objeto it em set apos while: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G
Objeto it: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
A
Objeto it: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G
Objeto it: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G
Objeto it: 
43987523987dhgdfhjfd
43987523987dhgdfhjfd
fsdjikughfkfhdg
G

The last thing that appears is a char of the tipe of the user, the first is key, then username, then password.

It's like the function of pushing back its not working! The object at start should always be admin, but it get replaced by the one that follows, and then, after the while, every variable in the vector are rewrite with the last object entered beside the char type val.

That method was working... like, today! And then that started to happen! Can someone help me? THank you guys for reading and helping

if you guys want a better view, here's the repo of the code: https://github.com/bruno-augusto-pinto/TP01-CPLUSPLUS

  • 4
    Form a proper [mcve], including test data producing your output, and the code setting up and calling your function. We can only guess what `Container` is, how `Objeto` relates to it, etc., and we shouldn't have to (guess, that is). I'm particularly interested in seeing your `operator >>` overload, which is required as part of your [mcve], and the definition and operation of `Objeto`. – WhozCraig Mar 05 '21 at 02:46
  • I filled in enough blanks to get your template instantiated and executed. It worked fine in that particular example. Therefore, you need to provide more information (i.e. the aforementioned [mre]). – JaMiT Mar 05 '21 at 02:52
  • I ran your code (except I used a `std::stringstream`) and everything worked as expected. How are you instantiating `setObjetos`. – WBuck Mar 05 '21 at 02:59
  • It works for me - here is an MVCE: https://onlinegdb.com/BJ6txXk7O With that one you need to pass one template parameter - here is a version that doesn't need any: https://onlinegdb.com/SJjCxm1md – Jerry Jeremiah Mar 05 '21 at 03:09
  • @WhozCraig, hey, I put more info into my body question, I guess that will help! – Bernardo Emery Mar 05 '21 at 03:38
  • @WBuck I guess the infos I edited in body shall fill your question... setObjetos is instatialized in "arquivos.hpp" that is the hpp of my files management, I read on web that we cant use templates classes on .cpp – Bernardo Emery Mar 05 '21 at 03:40
  • https://github.com/bruno-augusto-pinto/TP01-CPLUSPLUS Here's the repo of that code, if you guys want know more – Bernardo Emery Mar 05 '21 at 03:42

1 Answers1

0
 Container objetos;

this is local and discarded.

Your Usuario needs to use std strings, not raw C buffers. It is probably using dangling pointers.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Hey, I'll try that. In first time I was doing it with strings for real! But my teacher said if I use strings I can't delete the objetc directly in file later, is that true? Thank you – Bernardo Emery Mar 05 '21 at 11:46
  • @BernardoEmery You can't delete the characters managed by the *strings*, but you can delete the object that contains the strings if you in turn `new`d it. But I don't see anything in your problem that would require you ever calling `new` or `delete`. – Yakk - Adam Nevraumont Mar 05 '21 at 16:03
  • hey, welll, for deleting things in file, i am getting it to vector, finding it in vector, doing vector.erase(it) and then rewriting the whole file. You think there's a better way? – Bernardo Emery Mar 05 '21 at 17:59