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

如何在Rust中每次提取GPS数据后自动更新切片范围?

解决GPS数据切片自动更新的问题

要实现每次提取Token后自动更新切片范围,核心是让提取函数同时返回提取到的Token和剩余的切片,后续调用基于新切片继续处理即可。以下是完整的修正实现:

修改后的代码

fn get_string_token(mut buff: &[u8], delimiter: u8) -> Result<(String, &[u8]), ()> {
    // 定位分隔符位置
    match buff.iter().position(|&ch| ch == delimiter) {
        Some(index) => {
            // 提取当前Token
            let token_slice = &buff[0..index];
            let token = String::from_utf8_lossy(token_slice).to_string();
            
            // 更新切片:跳过当前分隔符,指向剩余数据
            buff = &buff[index + 1..];
            
            Ok((token, buff))
        }
        None => {
            // 处理最后一个字段(无后续分隔符)
            let token = String::from_utf8_lossy(buff).to_string();
            Ok((token, &[]))
        }
    }
}

fn extract_data(mut buff: &[u8]) {
    // 第一次提取:$GNGGA
    let (token, remaining) = get_string_token(buff, b',').unwrap();
    buff = remaining;
    println!("第一个字段: {}", token);

    // 第二次提取:062735.00
    let (token, remaining) = get_string_token(buff, b',').unwrap();
    buff = remaining;
    println!("第二个字段: {}", token);

    // 第三次提取:3150.788156
    let (token, remaining) = get_string_token(buff, b',').unwrap();
    buff = remaining;
    println!("第三个字段: {}", token);

    // 可继续提取后续字段...
}

fn main() {
    // 模拟填充GPS数据到缓冲区
    let gps_data = b"$GNGGA,062735.00,3150.788156,N,11711.922383,E,1,12,2.0,90.0,M,,M,,*55";
    let mut buff: [u8; 1024] = [0; 1024];
    buff[..gps_data.len()].copy_from_slice(gps_data);
    
    extract_data(&buff[..gps_data.len()]);
}

关键修改说明

  1. 返回值调整:将原函数的Result<String, ()>改为Result<(String, &[u8]), ()>,每次提取后同时返回Token和剩余切片,实现自动更新范围。
  2. 切片更新逻辑:找到分隔符后,直接将切片指向buff[index + 1..],跳过当前分隔符,确保下一次提取从新位置开始。
  3. 空字段兼容:移除原代码中end_index - start_index >1的判断,保留NMEA协议中空字段(如,,)的提取,返回空字符串符合协议规则。
  4. 末尾字段处理:当找不到分隔符时,直接提取剩余全部数据作为最后一个字段,避免遗漏。

批量提取优化

如果需要一次性提取所有字段,可通过循环简化代码:

fn extract_all_fields(mut buff: &[u8]) -> Vec<String> {
    let mut fields = Vec::new();
    loop {
        match get_string_token(buff, b',') {
            Ok((token, remaining)) => {
                fields.push(token);
                if remaining.is_empty() {
                    break;
                }
                buff = remaining;
            }
            Err(_) => break,
        }
    }
    fields
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 16:42:50