Newsgroup: it.comp.lang.c++
Titolo: Problemi con map e string.

Salve!
Un membro di una classe č un puntatore ad una mappa, dichiarato cosě:
map<const string, vector<Classe> > *Sezioni;
che viene regolarmente inizializzato con new nei costruttori.
Nel metodo seguente, a quella mappa dovrebbero venire assegnati dei
valori, ma, controllando col debugger, ho visto che map<> immagazzina
una string vuota, non quella passatale.
unsigned Istituto::NuovaSezione(const string &nome)
{
 
        if(Sezioni->count(nome)) return E_SEZIONE_ESISTENTE;
        Sezioni->insert(
        std::pair<const string, vector<Classe> >(nome, vector<Classe>())
        );
        (*Sezioni)[nome].resize(CLASSI_PER_SEZIONE);
        return 0;
}
Cosa sbaglio?
Grazie
-- 
Per l'e-mail rimuovere le maiuscole e gli underscore

 Cosa sbaglio?
non mi pare ci siano errori in quello che hai postato, ma come costruisci la
mappa? Prova a farti stampare sempre il contenuto delle chiavi alla fine di
NuovaSezione:
map<const string, vector<int> >::iterator i;
for (i = Sezioni->begin(); i != Sezioni->end() ;i++)
    cout << (*i).first<<endl;

 chiavi alla fine di NuovaSezione:
La mappa la costruisco con la funzione che ho postato nel primo post,
quindi nulla di strano. Aggiungo elementi al vector che è associato ad
ogni chiave della mappa con questa funzione (scusate la formattazione):
unsigned Istituto::NuovaClasse(const string &classe)
{
        Percorso _classe;
        Estrai(classe, _classe);
 
        if(_classe.classe > 4) return E_CLASSE_INESISTENTE;
        if(!Sezioni->count(_classe.sezione)) return E_NO_SEZIONE;
        if((*Sezioni)[_classe.sezione].size()==CLASSI_PER_SEZIONE) return
E_MAX_CLASSI;
        //Nel caso in cui si voglia creare una classe già presente
        if((*Sezioni)[_classe.sezione].size() > _classe.classe) return
E_CLASSE_ESISTENTE;
        (*Sezioni)[_classe.sezione].insert((*Sezioni
[_classe.sezione].begin()+_classe.classe, Classe());
        return 0;
}
Mi ritorna sempre al secondo `if'.
Ho fatto come mi hai suggerito, di stampare le chiavi, e sono risultate
essere quelle che avevo inserito; non riesco a capire.
Grazie e ciao.


if(!Sezioni->count(_classe.sezione)) return E_NO_SEZIONE;
Si ma dove hai inizializzato _classe.sezione? è ovvio che non venga mai
trovata se il vettore di classi tu lo inizializzi in questo modo:
Sezioni->insert(std::pair<const string, vector<Classe> >(nome,
vector<Classe>()));
che mette nella mappa in corrispondenza della chiave 'nome', un vettore
vuoto di oggetti Classe.
vector<Classe>(), chiama il costruttore di vector che a sua volta richiama
il costruttore di default di Classe ossia Classe().
Secondo me dovresti farti un costruttore del tipo Classe(const std::string&
nome_sezione): sezione(nome_sezione) e inizializzare il vettore con le 3
classi prima dell'insert:
unsigned Istituto::NuovaSezione(const string &nome)
{
vector<Classe> v;
for 1 ...CLASSI_PER_SEZIONE
{
 Classe cl(nome);
 v.push_back(cl);
}
...
 Sezioni->insert(std::pair<const string, vector<Classe> >(nome, v));
...
//Togli il resize, non ce n'è bisogno
return 0;
}

vuoto di oggetti Classe.
Che il vector sia vuoto non implica nulla, perché map<> associa la
chiave ad un'istanza di vector<>, che esiste comunque, anche se vuota.
#include <iostream>
#include <map>
#include <utility>
#include <string>
#include <vector>
using std::cout;
using std::endl;
using std::string;
class A{
        public:
        A(){cout << "A()" << endl;}
        A(const A&){cout << "A(const A&)" << endl;}
};
int main()
{
        std::map<const string, std::vector<A> > mappa;
        mappa.insert(std::pair<const string, std::vector<A> >
("A",std::vector<A>()));
        cout << mappa.count("A") << endl;
        mappa["A"].resize(4);
        return 0;
}
[cut]
Ciao e grazie


 chiave ad un'istanza di vector<>, che esiste comunque, anche se vuota.
Sono d'accordo che è corretto scrivere
Sezioni->insert(std::pair<const string, vector<Classe> >(nome,
vector<Classe>()));
pensavo che dentro l'oggetto Classe avessi messo anche il nome della sezione
di appartenenza, in modo da ritrovarlo tramite Estrai.
Ciao


una string vuota
Inoltre.. potresti specificare quale č la stringa vuota non immagazzinata?
dentro Classe? Da ciň che hai postato sembrava che ciň che era vuoto era la
chiave, ma non č cosě se le chiavi te le ritrovi stampate... spiegati
meglio... :o)

 possibile trovare qualcosa nella mappa se non gli passi la sezione.
La struttura Percorso è definita così:
struct Persorso{
        unsigned classe;
        string sezione;
};
Mentre questa è Estrai(), che funziona perfettamente:
void Istituto::Estrai(const string &sorgente, Percorso &o) const
{
        string temp;
        temp=string(sorgente, 0, sorgente.find(" "));
        o.sezione=string(sorgente.substr(temp.size()+1));
        o.classe=temp[0]-'0'-1;
}
Controllando con un debugger, in Istituto::NuovaClasse() le chiavi sono
presenti in Sezioni, ma si tratta di string vuote, mentre in
NuovaSezione le chiavi sono corrette!
Mah.


 stampate... spiegati meglio... :o)
In Istituto::NuovaSezione() le chiavi di Sezioni sono corrette; mentre,
controllandole in Istituto::NuovaClasse(), sono vuote.
Ciao


(nome,vector<Classe>()));
   (*Sezioni)[nome].resize(3);
   return 0;
}
void Estrai(const string &sorgente, Percorso &o) const <<QUESTA E'OK
{
   string temp;
  char tmp[50];
  strcpy(tmp,sorgente.c_str());
   temp=string(sorgente, 0, sorgente.find(" "));
  strcpy(tmp,sorgente.substr(temp.size()+1).c_str());
        o.sezione=sorgente.substr(temp.size()+1);
        o.classe=temp[0]-'0'-1;
}
unsigned NuovaClasse(const string &classe)
{
  map<const string, vector<Classe> >::iterator i;
  for (i = Sezioni->begin(); i != Sezioni->end() ;i++) {
   cout << (*i).first<<endl;
  } << STAMPA TUTTE LE CHIAVI!
        Percorso _classe;
        Estrai(classe, _classe);
        if(_classe.classe > 4) return 1;
        if(!Sezioni->count(_classe.sezione))
               return 2; //<< DA TE ESCE QUI
        //COMMENTO TUTTO IL RESTO!
       // if((*Sezioni)[_classe.sezione].size()==3) return 0;
        //Nel caso in cui si voglia creare una classe già presente
       // if((*Sezioni)[_classe.sezione].size() > _classe.classe) return 4;
//(*Sezioni)[_classe.sezione].insert((*Sezioni[_classe.sezione].begin()+_cla
sse.classe, Classe());
        cout << "OK"<<endl; //DA ME ARRIVA SIN QUI!
        return 0;
}
};
int main()
{
 Istituto i;
 i.NuovaSezione("a");
 i.NuovaSezione("c");
 i.NuovaClasse("1 c");
}
Ciao