C ++:列表元素从容器中消失

时间:2016-03-09 21:51:48

标签: c++ list stl containers

我正在调用一个函数从两个文件中读取一些数据并将其插入到Corso类的实例中。该类包含一个校友列表,每个校友都有一个必须填充的考试列表,这是leggiEsame()完成的。对leggiEsame()的第一次调用正确地添加了数据。然而,第二次调用似乎将考试添加到上一次,但在某些时候,新数据消失了。我正在调用main中的函数:

#include <iostream>
#include <Corso.h>

using namespace std;

int main()
{
    Corso c = Corso();
    c.leggiEsame("informatica.txt", Esame(1, "Informatica", "Danilo Franchini", 31, 18, 0, 10));
    c.leggiEsame("analisi.txt", Esame(2, "Analisi", "Marco Giovannetti", 31, 18, 0, 10));
    c.stampa();
    return 0;
}

leggiEsame()实现如下:

void Corso::leggiEsame(string path, Esame e)
{
FILE *f = fopen(path.c_str(), "r");
if(f==NULL)
    printf("File non valido.\n");

CodPersona cod_p;
NumMatricola num_m;
char str_voto[20];
float voto;
Alunno al = Alunno();

while(!feof(f))
{
    char format[100] = "%[^\t]\t%[^\t]\t%[^\t]%*[^\n]\n";
    fscanf(f, format, cod_p, num_m, str_voto);

    if(string(str_voto)=="RIMANDATO")
        voto = RIMANDATO;
    else if(string(str_voto)=="30 e Lode")
        voto = LODE;
    else if(string(str_voto)=="ASSENTE")
        voto = ASSENTE;
    else
        voto = atof(str_voto);

    e.setVoto(voto);

    al.setCodPersona(string(cod_p));
    al.setNumMatricola(string(num_m));
    aggiornaAlunno(al, e);
    /*Alunno a = *cercaAlunno(al);
    printf("Alunno %s aggiornato, ha %d esami\n", a.numMatricola().c_str(), a.esami().size());*/
}

fclose(f);
}

aggiornaAlunno()执行以下操作:

void Corso::aggiornaAlunno(Alunno a, Esame e)
{
Alunno a_found;
list<Alunno>::iterator it = cercaAlunno(a);
/// cerco l'alunno nella classe, se è già presente (iteratore diverso da m_alunni.end())
/// se l'alunno esiste già allora aggiorna i dati anagrafici dell'alunno
/// altrimenti aggiunge l'alunno alla classe.
if(it!=m_alunni.end())
{
    a_found = *it;
    a_found.aggiornaDati(a);
    /// se l'alunno già esistente non contiene l'esame allora lo aggiunge
    if(!a_found.contieneEsame(e, 0))
    {
        a_found.aggiungiEsame(e);
        printf("Aggiunto esame %d su %d a %s\n", e.id(), a_found.esami().size(), a_found.numMatricola().c_str());
    }
}
else
{
    printf("nuovo alunno\n");
    a.aggiungiEsame(e);
    aggiungiAlunno(a);
}
}

&#34; else&#34;条件的分支似乎工作正常,因为它添加了第一个读数的数据,而第二个调用aggiungiEsame():

void Alunno::aggiungiEsame(Esame e)
{
m_esami.push_front(e);
printf("Aggiunto esame %d a %s, n esami: %d\n", e.id(), m_num_matricola.c_str(), m_esami.size());
}

在此函数中,输出正常,似乎新数据已添加到每个考试列表,因为大小输出2,也在aggiornaAlunno()内。 当函数返回leggiEsame()时,列表的大小再次输出1,即使没有删除。 我希望你能提前帮助,谢谢你。

1 个答案:

答案 0 :(得分:2)

您不是要向现有的Alunno对象添加数据,而是将其添加到对象的副本中。 a_found = *it*it的内容复制到a_found,但它们是单独的对象。一旦a_found超出范围,它就会被破坏,以及你添加到它的任何东西。