c - 链接 list/libxml - 搜索特定类型的下一个元素并检查列表结尾

c - linked list/libxml - search next element of certain type and check for end of list

我正在尝试查找链表的下一部分 XML_ELEMENT_NODE 并在找到或到达列表末尾时停止:

do
{
    cur = cur->next;
} while (cur->type != XML_ELEMENT_NODE && cur != NULL);

所以我先得到next,因为如果我先检查我会卡在相同的部分并且不会进步。问题是当我到达终点 cur == NULL 时,我无法检查类型,因为我在 NULL 并且显然无法获得类型。有没有一个优雅的解决方案,因为我能想到的都需要我在循环中设置的替换变量,这样我就可以在 while() 中检查它们。我认为 break 不是一个选项。

试试这个:

while(cur->next !=NULL && cur->next->type != XML_ELEMENT_NODE) {
    cur = cur->next;
}
// at this point, the next element, if it exists, is of type XML_ELEMENT_NODE
// if it doesn't exist, cur->next will be NULL
cur = cur->next;

交换 && 运算符周围的条件:

do
{
    cur = cur->next;
} while (cur != NULL && cur->type != XML_ELEMENT_NODE);

这是因为如果第一个条件是 falsecurNULL),它将停止,因为如果第一个条件满足 && 运算符将停止不评估为 true。因此,如果 curNULL,它将停止评估条件并且不会尝试取消引用 nyll 指针

你一开始就没有检查cur是否好。我建议

while (cur != NULL) {
    if (cur->type == XML_ELEMENT_NODE)
        break;
    cur = cur->next;
}
if (cur != NULL) {
// ... success
}

EDIT 因为 OP 说他已经检查过 cur 并且也不喜欢 break 这是我的修订版,但是这个 still 在循环开始而不是结束时检查 cur

while (cur != NULL && cur->type != XML_ELEMENT_NODE)
    cur = cur->next;
}
if (cur != NULL) {
// ... success
}

您应该遵循一定的迭代流程。通常,您必须 永远不会 取消引用 空指针 ,因此您始终必须确保 curr 不是 空指针(简称:curr != NULL).

如果出于任何原因需要先获取下一个元素,则应使用:

while ( curr != NULL ) {

    curr = curr->next;
    if ( (curr != NULL) && (curr->type == XML_ELEMENT_NODE) )
        break;
}

但更好的方法是始终在当前节点上操作(这就是为什么要这样调用指针)。如果你知道curr不是NULL(由前面的代码确定),你可以使用:

// from some previous code, you have:
curr = curr->next;

... (do something unrelated, i.e. do not dereference curr if null-pointer)
while ( (curr != NULL) && (curr->type != XML_ELEMENT_NODE) ) {
    curr = curr->next;
}

在任何循环之后,您必须测试 curr != NULL 以在取消引用 curr.

之前捕获列表结束条件

请注意 curr 始终是当前节点(您开始 with/working 的节点。