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

C++11解析NMEA-0183时正则匹配出现缓冲区损坏问题求助

C++11解析NMEA-0183 GPS报文缓冲区损坏问题

问题描述

使用C++11读取NMEA-0183格式的GPS报文,代码重构后出现缓冲区损坏现象,无法定位原因,寻求解决帮助。

实际运行日志

GPS: probably data
GPS: $GPGLL,4851.87109,N,00226.20521,E,092741.00,A,A*6D
GPS: match is: 1 | 5 matches
GPS: match #0: 17a30a0 | buffer: 5f452ee0
GPS: match #0: B2z
GPS: match #1: 5f452ed0 | buffer: 5f452ee0
GPS: match #1: 
GPS: match #2: 5f452ed0 | buffer: 5f452ee0
GPS: match #2: N
GPS: match #3: 5f452ed0 | buffer: 5f452ee0
GPS: match #3: 00226.20521
GPS: match #4: 5f452ed0 | buffer: 5f452ee0
GPS: match #4: E
GPS: match is: latitude:0.000000 | longitude: 2.436754
GPS: end of processing

期望运行结果

(注:以下为GPRMC报文,与上述GPGLL报文处理逻辑一致)

GPS: probably data
GPS: $GPRMC,164548.00,A,4851.85459,N,00226.22224,E,0.721,,060923,,,A*7F
GPS: match is: 1 | 5 matches
GPS: match #0: GPRMC,164548.00,A,4851.85459,N,00226.22224,E
GPS: match #1: 4851.85459
GPS: match #2: N
GPS: match #3: 00226.22224
GPS: match #4: E
GPS: match is: latitude:48.864243 | longitude: 2.437037
GPS: end of processing

相关代码

#include <iostream>
#include <regex>

/// @brief Returns the 01131.324 (Longitude 11 deg 31.324') coordinate as a
/// float
/// @param sReading The string of the coordinate
/// @return the float version
float latitudeDeegresToFloat(char const *sReading) {
  char sDegrees[2 + 1] = {sReading[0], sReading[1], 0};
  float degrees = (float)strtod(sDegrees, NULL);
  float minutes = (float)strtod(sReading + 2, NULL);
  const float latitude = degrees + minutes / 60.0;

  return latitude;
}

/// @brief Returns the 11131.324 longitude (111 deg 31.324') coordinate as a
/// float
/// @param sReading The string of the coordinate
/// @return The float version
float longitudeDeegresToFloat(char const *sReading) {
  char sDegrees[3 + 1] = {sReading[0], sReading[1], sReading[2], 0};
  float degrees = (float)strtod(sDegrees, NULL);
  float minutes = (float)strtod(sReading + 3, NULL);
  const float longitude = degrees + minutes / 60.0;

  return longitude;
}

int main() {
  float latitude, longitude;

  printf("GPS: probably data\n");

  /// Regex string match
  std::smatch match;

  char buffer[256 * 4] = "$GPGLL,4851.87109,N,00226.20521,E,092741.00,A,A*6D";

  printf("GPS: %s\n", buffer);
  bool found = false;

// == Is is a GPGLL message Geographic Acquisition
#define COMMAND "$GPGGA"
  if (strncmp(buffer, COMMAND, sizeof COMMAND - 1) == 0) {

    //$GPGGA,123519,4807.038,N,01131.324,E,
    std::string str(buffer + 1); // Skip leading $
    std::regex rgx("GPGGA,[^,]*,([0-9\\.+-]+),(N|S),([0-9\\.+-]*),(E|W)\\.?");
    found = std::regex_search(str, match, rgx);
  }
  // == Is is a GPGLL message Geographic Latitude Longitude
#define COMMAND "$GPGLL"
  else if (strncmp(buffer, COMMAND, sizeof COMMAND - 1) == 0) {

    std::string str(buffer + 1); // Skip leading $
    std::regex rgx("GPGLL,([0-9\\.+-]+),(N|S),([0-9\\.+-]*),(E|W)\\.?");
    found = std::regex_search(str, match, rgx);
  }

// == Is is a GPRMC message (lat, long)
#define GPRMC "$GPRMC"
  else if (strncmp(buffer, GPRMC, sizeof GPRMC - 1) == 0) {
    std::string str(buffer + 1); // Skip leading $
    std::regex rgx("GPRMC,[^,]*,A,([0-9\\.+-]+),(N|S),([0-9\\.+-]*),(W|E)\\.?");
    found = std::regex_search(str, match, rgx);

  } else {
    printf("GPS: not a message to process but '%s'\n", buffer);
    return 3;
  }

  printf("GPS: match is: %d | %d matches\n", found, match.size());
  if (!found)
    return 1;

  int i = 0;

  for (auto m : match) {
    printf("GPS: match #%d: %x | buffer: %x\n", i, m.str().c_str(), buffer);
    printf("GPS: match #%d: %s\n", i, m.str().c_str());

    switch (i) {
    // Latitude
    case 1:
      latitude = latitudeDeegresToFloat(m.str().c_str());
      break;
    // Latitude direction
    case 2:
      if (m.str().compare("S") == 0)
        latitude = -latitude;
      break;
    // Longitude
    case 3:
      longitude = longitudeDeegresToFloat(m.str().c_str());
      break;
    case 4:
      if (m.str().compare("W") == 0)
        longitude = -longitude;
      break;
    }

    i++;
  }
  printf("GPS: match is: latitude:%f | longitude: %f\n", latitude, longitude);

  // == End of GPS processing
EndOfGpsProcessing:
  printf("GPS: end of processing\n");

  if (latitude == 0 && longitude == 0) {
    printf("GPS: won't publish Null Island\n");
    return 2;
  }

  return 0;
}

内容的提问来源于Stack Exchange,提问作者Stéphane de Luca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 14:37:31