Currently I am working on GPS clock for the Time and Space Projects and I was going through my old repository to salvage few lines of code I wrote few years ago. In one of my earlier projects, I was working on parsing GPS data to obtain location coordinates and date/time values. After writing a regex like string parser that took nearly 50ms processing time. I thought there must be a better and faster way to parse a string that is in a predefined pattern. Since GPS data I receive is usually in csv format, I decided to check c/c++ implementation of .csv files and found a standard function called "sscanf".
The full form of sscanf is string scanf, which basically means it accept and read string data as input, as opposed to regular scanf which takes in user fed data as input. Functionally, it does the opposite of sprintf. In sprintf, the values in variables get placed in predefined string format into a character array whereas in sscanf, formatted character array is matched with the predefined string format and the values will be stored in variable.
In the below code snippet I have created a simple function that parses the date & time present in a character array. As we know, timestamps usually follow the "yyyy-mm-dd hh:mm:dd", it is quite easy to create a string format that captures integer values and assign to variables. I have explicitly stated the digits with format specifier as %02 to make sure leading zero will be printed.
#include <stdio.h> #include <stdint.h> #include <string.h> typedef struct { int year; int month; int day; int hour; int minutes; int seconds; } time_data; int main () { char *timestamp = "2023-05-23 21:05:32"; time_data tm_dt; char ouput_buffer[30]; // note the '&' before the variable names, we are storing the values in address of variables like we do in scanf. sscanf (timestamp, "%04d-%02d-%02d %02d:%02d:%02d", &tm_dt.year, &tm_dt.month, &tm_dt.day, &tm_dt.hour, &tm_dt.minutes, &tm_dt.seconds); sprintf (ouput_buffer, "%04d-%02d-%02d %02d:%02d:%02d", tm_dt.year, tm_dt.month, tm_dt.day, tm_dt.hour, tm_dt.minutes, tm_dt.seconds); printf ("%s", ouput_buffer); return 0; }
Note : For known size & format of simple strings, this function will be quite useful. This code by no means is a production suitable code and it is not advisable to use sscanf or most of the functions in stdio without checking the size first.