NMEA0183数据解析sscanf与token

实现1 sscanf

#include <stdio.h>

int main() {
    // 原始的 NMEA 数据字符串
    char data[] = "$GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D";

    // 变量来存储解析后的数据
    char type[6];
    char latitude[11];
    char latitude_dir;
    char longitude[12];
    char longitude_dir;
    char utc_time[11];
    char status;
    char checksum[4];
    
    // 使用 sscanf 解析数据
    int parsed = sscanf(data, "$%5[^,],%10[^,],%c,%11[^,],%c,%10[^,],%c*%3s", 
                        type, latitude, &latitude_dir, longitude, &longitude_dir, 
                        utc_time, &status, checksum);
    
    // 检查解析是否成功
    if (parsed == 8) {
        // 输出解析结果
        printf("类型: %s\n", type);
        printf("纬度: %s %c\n", latitude, latitude_dir);
        printf("经度: %s %c\n", longitude, longitude_dir);
        printf("UTC时间: %s\n", utc_time);
        printf("状态: %c\n", status);
        printf("校验和: %s\n", checksum);
    } else {
        printf("解析失败\n");
    }

    return 0;
}

实现2 strtok

#include <stdio.h>
#include <string.h>

int main() {
    // 原始的 NMEA 数据字符串
    char data[] = "$GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D";
    
    // 定义分隔符
    const char *delim = ",*";
    
    // 获取数据部分
    char *token = strtok(data, delim);
    
    // 验证是否是 GPGLL 语句
    if (strcmp(token, "$GPGLL") != 0) {
        printf("不是 GPGLL 语句\n");
        return 1;
    }
    
    // 解析各个字段
    char *latitude = strtok(NULL, delim);
    char *latitude_dir = strtok(NULL, delim);
    char *longitude = strtok(NULL, delim);
    char *longitude_dir = strtok(NULL, delim);
    char *utc_time = strtok(NULL, delim);
    char *status = strtok(NULL, delim);
    char *checksum = strtok(NULL, delim);
    
    // 输出解析结果
    printf("纬度: %s %s\n", latitude, latitude_dir);
    printf("经度: %s %s\n", longitude, longitude_dir);
    printf("UTC时间: %s\n", utc_time);
    printf("状态: %s\n", status);
    printf("校验和: %s\n", checksum);
    
    return 0;
}

实现方法1:strtok()

#include <stdio.h>
#include <string.h>

int main() {
    char *str = "$GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D";
    char *token;
    const char *delim = ",*"; // 定义分隔符为逗号和星号

    // 使用strtok分割字符串前,先复制一份,因为strtok会修改原字符串
    char *strCopy = strdup(str);

    // 获取第一个token
    token = strtok(strCopy, delim);

    while (token != NULL) {
        printf("Token: %s\n", token);
        // 获取下一个token
        token = strtok(NULL, delim);
    }

    // 如果需要释放strdup分配的内存
    free(strCopy);

    return 0;
}

实现方法2:strtok_r()

#include <stdio.h>
#include <string.h>

// 函数声明
void parseGPGLL(const char *sentence);

int main() {
    const char *gpsData = "$GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D";
    parseGPGLL(gpsData);
    return 0;
}

void parseGPGLL(const char *sentence) {
    char *token;
    char *str = strdup(sentence); // 使用strdup复制字符串,以便使用strtok
    char *saveptr;
    char utcTime[15]; 

    // 提取语句类型
    token = strtok_r(str, ",", &saveptr);
    printf("Sentence Type: %s\n", token);

    // 提取纬度
    token = strtok_r(NULL, ",", &saveptr);
    double latitude = atof(token); // 将纬度转换为浮点数
    token = strtok_r(NULL, ",", &saveptr);
    char latitudeHemisphere = token[0]; // N或S

    // 提取经度
    token = strtok_r(NULL, ",", &saveptr);
    double longitude = atof(token); // 将经度转换为浮点数
    token = strtok_r(NULL, ",", &saveptr);
    char longitudeHemisphere = token[0]; // E或W

    // 提取UTC时间
    token = strtok_r(NULL, ",", &saveptr);
    strncpy(utcTime, token, sizeof(utcTime) - 1); // 复制UTC时间到新数组
    utcTime[sizeof(utcTime) - 1] = '\0'; // 确保字符串以空字符结尾

    // 提取定位状态
    token = strtok_r(NULL, "*", &saveptr);
    char status = token[0]; // A表示有效定位,V表示无效定位

    // 提取校验码
    token = strtok_r(NULL, "*", &saveptr);


    // 打印结果
    printf("Latitude: %f°%c\n", latitude, latitudeHemisphere);
    printf("Longitude: %f°%c\n", longitude, longitudeHemisphere);
    printf("UTC Time: %s\n", utcTime);
    printf("Status: %c\n", status);
    printf("Checksum: %s\n", token);

    free(str); // 释放复制的字符串
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值