我正在尝试从具有特定结构的文件中解析数据。这个数据将被写入双链表(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
答案 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 + ]
^ |
| |
+---------------------------------------------+
如果您在纸上完成了自己正在做的事情,那么您应该能够更正您的代码。