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
相关产品推荐
相关产品推荐

