【问题标题】:C - Extern structC - 外部结构
【发布时间】:2020-02-16 22:22:07
【问题描述】:

我正在使用结构来处理 NMEA 消息,但我不知道是什么,处理它时出了点问题。所以,我有 NMEA_parse.h:

/* GPRMC */
 #define TIME   2U
 #define LAT        4U
 #define LON        6U
 #define SPD        8U
 #define ANG        9U
 #define DATE   10U

extern struct gprmc{
    char time[10];
    char latitude[10];
    char longitude[10];
    char speed[10];
    char angle[10];
    char date[10];
}gprmc_datas;

NMEA_parse.c:

#include "NMEA_parse.h"

struct gprmc gprmc_datas;

static void fill_data (char* param_in)
{
    uint8_t i = 0U;             
    char* trunk;                
    char trunk_datas[20U][10U]; 

    trunk = strtok(param_in, ",");      
    while(trunk != NULL)
    {
        i++;        
        if(i > 20) { i = 0; }

        strcpy(trunk_datas[i],trunk);
        trunk = strtok (NULL, ",");     
    }

    if(memcmp(trunk_datas[1U],"GPRMC",6U) == 0U)
    {
        strcpy(gprmc_datas.time,trunk_datas[TIME]);
        strcpy(gprmc_datas.latitude,trunk_datas[LAT]);
        strcpy(gprmc_datas.longitude,trunk_datas[LON]);
        strcpy(gprmc_datas.date,trunk_datas[DATE]);
        strcpy(gprmc_datas.time,trunk_datas[TIME]);
    }
}

main.c:

#include <stdio.h>
#include "NMEA_parse.h"

int main(void)
{
    char *message = "$GPRMC,182127.00,A,4753.47678,N,02022.20259,E,0.837,,161019,,,A*7C\r\n";
    char *mes     = "$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A";
    proc_sentence(message);
    printf("\ntime: %s\n", gprmc_datas.time);
    printf("latitude: %s\n", gprmc_datas.latitude);
    printf("longitude: %s\n", gprmc_datas.longitude);
}

proc_sentence 函数将数据传递给 fill_data(),如果消息有效(校验和等) 当我使用 mes 作为输入时,一切正常,但是当我切换到 message 时,显示一些异常,因为结果如下:

时间: 182127.00

纬度: 4753.4767802022.2025E

经度: 02022.2025E

你知道出了什么问题吗?

【问题讨论】:

  • 4753.47678 是 10 个字符,并且您的字段中没有额外的 '\0' 字节。
  • 02022.20259 是 11 个字符(甚至不包括额外的字节),因此完全不适合 10 个字符的数组。你所有的数组都应该是 64 字节。在字符串文字上使用 strtok 会导致未定义的行为。 char *messagechar *mes 应该是 char message[]char mes[]
  • 感谢帮助,我没有考虑结束字节('\0')。增加数组的存储解决了这个问题

标签: c++ c string struct extern


【解决方案1】:

如果将struct中的latitude[10]改为latitude[12],也可以使用字符串“message”。

【讨论】:

    【解决方案2】:

    与几乎所有其他关于使用 scanf 的 SO 问题不同,您的问题实际上是一个急需解决的问题。毕竟,如果机器写了它,机器就可以读取它,对吧?

    使用 C 的字符串文字连接,我非常接近用一个函数填充结构:

      int n = sscanf( message,
              "%[^,]," 
              "%[^,]," 
              "%*[^,],%[^,]," 
              "%*[^,],%[^,]," 
              "%*[^,],%[^,]," 
              "%[^,],"    
              "%[^,],", 
              label,
              gprmc.time, 
              gprmc.latitude, 
              gprmc.longitude, 
              gprmc.speed, 
              gprmc.angle, 
              gprmc.date );
    

    这利用了很少使用的正则表达式说明符,我们在其中查找以逗号分隔的非逗号%[^]%*[^] 指定跳过该字段。

    【讨论】:

      猜你喜欢
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-25
      • 2015-02-02
      • 1970-01-01
      • 2019-03-30
      • 1970-01-01
      相关资源
      最近更新 更多