从列表中读取C ++文件

时间:2014-05-22 02:24:35

标签: c++ list file

我正在尝试从具有特定结构的文件中解析数据。这个数据将被写入双链表(Next和prev)我已经使函数从文件中读取数据并放入时间列表,但当我尝试将其传递到最终列表时,不知何故数据不见了。我认为这是因为列表的字段之间链接不好,但我找不到确切的链接问题,代码是这样的:

void LeerArchivo (Persona **p, string doc){
    int n = 0;
    Persona *Aux = *p;
    Persona *t = new Persona;
    Fecha *f = new Fecha;
    Vehiculo *v = new Vehiculo;
    ifstream Archivo(doc.c_str()); // Abro el archivo en modo lectura

    if (Archivo)
    {
        while (!(Archivo.eof())){ // Mientras archivo no llegue al final del documento (end of file) ejecuta las instrucciones
            n = 0;
            Archivo >> t->Cedula; // Paso la primera linea de archivo al campo cedula del primer registro persona
            Archivo >> t->Nombre;
            Archivo >> t->Apellido;
            Archivo >> f->Dia;
            Archivo >> f->Mes;
            Archivo >> f->Annio;
            t->Nacimiento = f;
            Archivo >> n; // Esto sera un integer 1 o 0 contenido en el archivo que indica si la persona tiene carro o no
            if (n){
                Archivo >> v->Placa;
                Archivo >> v->Marca;
                Archivo >> v->Modelo;
                Archivo >> v->Color;
                Archivo >> v->Annio;
                v->Propietario = t;
                t->Carro = v;
            }
            else
                t->Carro = NULL;            

            if(Aux){
                t->Siguiente = NULL;
                (Aux)->Siguiente = t;
                t->Anterior = Aux;
                Aux = t;
                Aux = (Aux)->Siguiente;
            }
            else{
                Aux = t;
                t->Siguiente = NULL;
                t->Anterior = NULL;
            };
        };
    }
    else
    {
        cout << "El archivo " << doc << " no existe" << endl;
    }
};

解析完成后,列表中剩下的唯一数据就是从文件中读取的最后一个寄存器,因此我确信数据被覆盖而不是被链接。

在链接部分,我也试过了这段代码

 if(Aux){
    (*p)->Siguiente = NULL;
    (*p)->Siguiente = t;
    t->Anterior = *p;
    *p = t;
    *p = (*p)->Siguiente;
}
else{
    *p = t;
    t->Siguiente = NULL;
    t->Anterior = NULL;
};

还有这个

if(Aux){
    (*p)->Siguiente = NULL;
    (*p)->Siguiente = t;
    t->Anterior = *p;
    *p = t;
}
else{
    *p = t;
    t->Siguiente = NULL;
    t->Anterior = NULL;
};

    *p = (*p)->Siguiente;

我将很感激有关代码的任何建议,谢谢:D

1 个答案:

答案 0 :(得分:2)

让我们通过你的最新尝试:

if(Aux)
    ...
else{
    *p = t;
    t->Siguiente = NULL;
    t->Anterior = NULL;
};

对于Aux == nullptr案例,这看起来不错。你最终应该:

p ---> *p = t ---> [ Siguiente nullptr
                     Anterior  nullptr ]

然后,对于第二次及以后的记录......

if(Aux){
    (*p)->Siguiente = NULL;
    (*p)->Siguiente = t;
    t->Anterior = *p;
    *p = t;
    *p = (*p)->Siguiente;
}
else ...

Aux仍然是nullptr,因为您在添加第一条记录后从未更新它,因此它永远不会进入此代码。相反,它用刚刚读取的记录替换列表中的第一个元素。要解决此问题,您可以添加...

Aux = *p;

...到您的else代码,然后后续记录将会到达:

    (*p)->Siguiente = NULL;
    (*p)->Siguiente = t;
    t->Anterior = *p;
    *p = t;
    *p = (*p)->Siguiente;

您已经设置了Siguiente两次......这是不对的!回到我们的数据,如果到目前为止只有一条记录,那么我们从上面的数据安排和我们新的*t记录开始:

p ---> *p ---> [ Siguiente nullptr          t ---> [ Siguiente unset
                 Anterior  nullptr ]                 Anterior  unset ]

(*p)->Siguiente = t;将左侧的Siguiente指针更改为地址t,新记录 - 听起来不错:

p ---> *p ---> [ Siguiente ---------------- t ---> [ Siguiente unset
                 Anterior  nullptr ]                 Anterior  unset ]

然后t->Anterior = *p;

p ---> *p ---> [ Siguiente ---------------- t ---> [ Siguiente unset
                 Anterior  nullptr ]                 Anterior  +     ]
                 ^                                             |
                 |                                             |
                 +---------------------------------------------+

这很有希望。但是你有这个代码......

    *p = t;

...这使* p指向新记录。你最终得到了这个:

p ---> *p ------------------------------------------+
                                                    |
                                                    v
               [ Siguiente ---------------- t ---> [ Siguiente unset
                 Anterior  nullptr ]                 Anterior  +     ]
                 ^                                             |
                 |                                             |
                 +---------------------------------------------+

然后*p = (*p)->Siguiente;,您已取消新旧节点的链接,并将*p留下未初始化指针的副本:

p ---> *p = unset

               [ Siguiente ---------------- t ---> [ Siguiente unset
                 Anterior  nullptr ]                 Anterior  +     ]
                 ^                                             |
                 |                                             |
                 +---------------------------------------------+

如果您在纸上完成了自己正在做的事情,那么您应该能够更正您的代码。