Although it's not mentioned in the question, it appears that you're receiving NMEA 0183 sentences. There are libraries (including free, open-source ones) for parsing such inputs, so I'm surprised to see hand-built code here. I recommend you choose a good library, and completely reimplement the code using the library.
Assuming you can't use any of the libraries for some reason, I'll continue with review.
You probably only want to recognise what2find
at the start of a line, rather than in any other positions in the string. Although it's unlikely, it's possible that it appears (perhaps in a sentence that includes an arbitrary label or comment field).
There are serious problems with the test program - specifically the multi-line string literal. I'm guessing from knowledge of the format that the sentences should all start at beginning of line:
char buffer[] ="$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47\r\n""$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39\r\n""$GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75\r\n""$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A\r\n""$GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*48\r\n";
This also shows a problem with the interface - is it necessary to require the input be modifiable? It seems reasonable that I should be able to pass a pointer to constant chars, and the example itself shows what2find
being passed a string literal (which is necessarily const char*
. It's also clearer for the reader if you write the destination capacity as sizeof dst
rather than as literal 50
.
Test should also perform a search for a sentence that exists in the input - at the moment, test coverage is very low.
Consider returning position and length of the result, and let the caller decide whether or not to copy. Alternatively, accept pointer to writeable characters, and null-terminate in-place - but note that that may preclude calling the function several times on the same data; it's more suited to line-by-line processing, perhaps with a callback for each sentence data type.
If you do need to copy within the function, there's no need to write your own strncpy()
function.
Rename temp
to something more descriptive; remove the empty statement following, and change if
/return
/else
to plain if
/return
:
int findString(const char *src, char *dst, size_t desLen, const char *what2find, char termChar){ char *start = strstr(src, what2find); if (!start) { return 0; } start += strlen(what2find); char *end = strchr(start, '\r'); size_t length = end - start; if (length + 1 > desLen) { return 0; } memcpy(dst, start, length); dst[length] = '\0'; return 1;}