You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言如何从指定偏移搜索char*子串?修复XML解析循环重复问题

修复XML解析循环重复匹配第一个<person>的问题

问题根源

当前代码的核心问题是:循环调用parseXML时始终传入原始buffer的起始地址,再加上parseXML内部直接从buffer开头搜索标签,导致每次迭代都只会匹配第一个<person>条目,无法从已处理的偏移位置继续扫描。


修复方案

1. 调整循环中的parseXML调用参数

每次调用时,传入偏移后的buffer指针(原始buffer加上已处理的总偏移量bytes_read_total),让parseXML从上次处理结束的位置开始搜索。

修改后的循环代码:

int bytes_read_total = 0;
while (bytes_read_total < bytes_received) {
        
    int bytes_read = 0;
    // 传入偏移后的指针,从已处理内容的下一个位置开始解析
    Person* person = parseXML(buffer + bytes_read_total, bytes_received - bytes_read_total, &bytes_read);

    if (person == NULL) break;

    bytes_read_total += bytes_read;
    savePerson(person);
}

2. 增强parseXML的边界检查与搜索逻辑

  • 确保起始标签<person>不超出当前传入的缓冲区范围
  • 从起始标签之后搜索结束标签</person>,避免匹配到无关的结束标签
  • 修正bytesRead的计算逻辑,同时新增内存分配失败的容错处理

修改后的parseXML函数起始部分:

#include <string.h>
#include <stdlib.h>

Person* parseXML(char* buffer, int bufSize, int* bytesRead) {
    // 初始化bytesRead,避免异常场景未赋值
    *bytesRead = 0;
    
    const char startTagStr[] = "<person>";
    const char endTagStr[] = "</person>";
    size_t startTagLen = strlen(startTagStr);
    size_t endTagLen = strlen(endTagStr);

    char* startTag = strstr(buffer, startTagStr);
    // 检查起始标签是否存在,且未超出缓冲区范围
    if (startTag == NULL || (startTag - buffer) + startTagLen > bufSize) {
        return NULL;
    }

    // 从起始标签之后搜索结束标签,避免匹配到前置的无效标签
    char* endTag = strstr(startTag + startTagLen, endTagStr);
    // 检查结束标签是否存在,且未超出缓冲区范围
    if (endTag == NULL || (endTag - buffer) + endTagLen > bufSize) {
        return NULL;
    }

    Person* person = newPerson();
    if (person == NULL) {
        return NULL;
    }
    
    // 计算当前person条目的总长度:从startTag到</person>结尾的字节数
    int personLength = (endTag - startTag) + endTagLen;

    char* personBuffer = (char*)malloc(personLength + 1);
    if (personBuffer == NULL) {
        // 内存分配失败时释放已创建的person,避免泄漏
        freePerson(person);
        return NULL;
    }
    memcpy(personBuffer, startTag, personLength);
    personBuffer[personLength] = '\0';

    // ... 此处保留原有的personBuffer解析逻辑

    free(personBuffer);
    // 设置本次处理的字节数
    *bytesRead = personLength;
    return person;
}

额外注意事项

  • 新增的边界检查可以避免内存越界访问,提升代码稳定性
  • 内存分配失败的容错处理防止了内存泄漏
  • 从起始标签后搜索结束标签的逻辑,避免了缓冲区中存在孤立</person>标签时的错误匹配

内容的提问来源于stack exchange,提问作者Oscar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:20:22