Limitations on Parsing GPS information using strstr and sscanf !!!

Source: Internet
Author: User
First of all, the methods in this article have limitations. In the case of GPS data defects, the resolution will not be successful!

 

Http://www.regexlab.com/zh/regref.htm

 

 

It is unrealistic to use sscanf or strtok to parse the following three statements and succeed:

Char str1 [] = "$ uplmc, 121252.000, A, 3958.3032, N, 11629.6046, E, 15.15, 359.95, 070306, A * 54 ";
Char str2 [] = "$ uplmc, 013244.013, V, 2949.0092, N, 12133.1459, E, 290908, N * 78 ";
Char str3 [] = "$ gprs mc, V, N * 53 ";

 

 

 

Use strstr and sscanf to parse GPS information

Author: Yang Shuo, a lecturer at Huaqing vision embedded College.

An important criterion to test whether a C programmer is qualified is to check his ability to operate strings. A qualified C programmer should be able to skillfully split, combine, convert the format, and search and locate strings, extract valid information from a pile of data.

For example, to create a GPS navigation project, we need to read the data sent by the GPS module in the form of ASCII code, and then process the data to extract the information we need. This involves many operations on strings. The following example uses strstr and sscanf functions to parse GPS data.

The format of GPS output data is as follows:

$ Gpgga, 121252.000, 3937.3032, N, 11611. * 6, E, 2.0, 45.9, 5.7, M,-0000, M, * 77

$ Uplmc, 121252.000, A, 3958.3032, N, 11629. * 6, E, 15.15, 359.95, 070306, A * 54

$ Gpvtg, 359.95, T, M, 15.15, N, 28.0, K, A * 04

$ Gpgga, 121253.000, 3937.3090, N, 11611.6057, E, 1.2, 44.6, 5.7, M,-0000, M, * 72

$ Gpgsa, A, 3, 14, 15, 05, 2.1, 18, 26, 1.2, 1.7 * 3D

$ Gpgsv, 84,067, 67,067, 49,312, 47,231, 30*70

$ Gpgsv, 32,199, 25,272, 21,140, 14,070, 20 * 7E

$ Gpgsv, 07,074, * 7d

We can see that the GPS module sends a lot of raw data, but usually we only need a part of the information to use it. For example, for the navigation function, we only need to start with $ gprs mc, it is enough to end a line with a linefeed. That is:

$ Uplmc, 121252.000, A, 3958.3032, N, 11629. * 6, E, 15.15, 359.95, 070306, A * 54

So what we need to do is to extract a row starting with $ gprs mc from the read data, and then parse the valid information such as the longitude and latitude, date and time.

Assume that the data read from the serial port is stored in the memory unit pointed to by a string pointer char * raw_buf. First, we use the strstr () provided by ansi c () the function finds the string ending with the linefeed '/N' starting with $ gprs mc:

/* Find "$ gprs mc" from raw_buf */

If (maid "))! = NULL)

{

For (I = 0; I <strlen (wellhandled_string); I ++)

{

If (wellhandled_string [I] = '/N ')

{

Wellhandled_string [I] = '/0'; // replace'/N' with null

}

}

}

The prototype of the strstr () function is declared as follows:

Char * strstr (const char * haystack, const char * needle );

The strstr () function can search for the first position of the string needle in the string haystack and return a pointer to the first address of the string needle. If no value is found, null is returned. Therefore, the above Code searches for the first position of $ gprs mc in the original data raw_buf and assigns the returned pointer to wellhandled_string. if the search is successful, wellhandled_string points to the string starting with $ gprs mc. Next, find the linefeed '/N' through a for loop and replace it with'/0', that is, the string Terminator. In this way, a string pointer wellhandled_string pointing to valid data is obtained.

The task is to extract the longitude and latitude, date and time information from wellhandled_string. This work can be implemented by powerful sscanf functions. The prototype of the sscanf function is as follows:

Int sscanf (const char * STR, const char * format ,...);

We are all familiar with the scanf function. scanf can read data that matches the specified format from the standard input stream. Sscanf reads data from const char * Str. It is powerful in that it can easily retrieve various types of data such as integers, floating points, and strings from strings, and it also has the matching function similar to regular expressions, by default, sscanf separates strings by spaces. If not, % [] can be used to specify the conditions for segmentation. For example, % [A-Z] indicates that all characters from A to Z are read, and % [^ A-Z] indicates that all characters between a-Z are filtered, that is, if any character between A and Z is encountered, the conversion immediately stops. For example:

Sscanf ("abcdefabcdef", "% [^ A-Z]", STR );

Printf ("% s/n", STR );

Result is: abcdef

Matching formats like % [^ A-Z] are strings that we encounter uppercase letters. With this matching method, we can operate strings flexibly to get the desired results.

Now we need to extract valid information from the following string:

$ Uplmc, 121252.000, A, 3958.3032, N, 11629. * 6, E, 15.15, 359.95, 070306, A * 54

The meaning of each field in the gprs mc is as follows:

$ Uplmc, <1>, <2>, <3>, <4>, <5>, <6>, <7>, <8>, <9>, <10>, <11>, <12> * hh <CR> <LF>

<1> UTC time, hhmmss (hour/minute/second) Format

<2> positioning status, A = valid, V = invalid

<3> latitude ddmm. Mmmm (degree) format (the preceding 0 will also be transmitted)

<4> latitude hemisphere N (northern hemisphere) or S (Southern Hemisphere)

<5> longitude dddmm. Mmmm (degree) format (the preceding 0 will also be transmitted)

<6> longitude hemisphere E (eastern longitude) or W (Western longitude)

<7> ground speed (000.0 ~ Section 999.9, the previous 0 will also be transmitted)

<8> ground heading (000.0 ~ 359.9 degrees. Based on the reference of zhenbei, the preceding 0 will also be transmitted)

<9> UTC date, in ddmmyy format

<10> magnetic angle (000.0 ~ 180.0 degrees, the previous 0 will also be transmitted)

<11> magnetic angle direction, E (East) or W (West)

<12> mode indication (output only in nmea0183 3.00, A = self-locating, D = differential, E = estimation, n = Invalid Data)

We extract 1 ~ 9. Store the information with a struct:

Typedef struct gps_info

{

Char utc_time [buf_size];

Char status;

Float latitude_value;

Char latitude;

Float longtitude_value;

Char longtitude;

Float speed;

Float azimuth_angle;

Char utc_data [buf_size];

} Gps_info;

Because each field is separated by a comma, we can use % [^,] to split the string so that the sscanf function can be used to extract valid information:

Sscanf (wellhandled_string, "$ uplmc, % [^,], % C, % F, % F, % [^,] ",

Rmc_info-> utc_time ,/

& (Rmc_info-> status), & (rmc_info-> latitude_value), & (rmc_info-> latitude ),/

& (Rmc_info-> longtitude_value), & (rmc_info-> longtitude), & (rmc_info-> speed ),/

& (Rmc_info-> azimuth_angle ),/

Rmc_info-> utc_data );

After this function is executed, the printed information stored in the struct gps_info struct is as follows:

Utc_time: 024813.640

Status:

Latitude: N latitude value: 3158.460693

Longtitude: E longtitude value: 11848.374023

Speed: 10.050000

Azimuth_angle: 324.269989

Utc_data: 150706

We can see that the sscanf function allows us to efficiently process strings.

"This article is written by Hua Qing vision http://www.embedu.org/index.htm"

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.