Sscanf Fun
23 January 2023

It is always surprising how well the C library holds together when you want to do certain tasks. It is ancient, unsafe (well lets call that sharp) and has evolved over a period of time giving it plenty of opportunity to pick up the many quirks it has.

However it is small-ish and mostly fits in your head.

One set of functions I never used for a long time were the scanf functions. This week I learnt a new trick.

I was parsing a fairly simple csv file that contains the lines like this

tree.png,38,48,2,2,0,0,38,48

It is a description of a texture region on a sprite sheet for a small game engine I am working on.

Now I could split this up based on the commas. Heck I could use strtok for that :) Ok I mean strtok_r but really it looks like a job for sscanf

The later parts are easy but then first element is the name of the original file and really I wanted to extract that without the .png to avoid the extra step of having to remove it. I wanted to read into a string the first part of the line until I hit a .. This is actually doable using sscanf and here it is.

char name[1024];
const int num_read = sscanf(line.begin, "%1023[^.].png,
                           %f,%f,%f,%f,%f,%f,%f,%f", 
                           name, &x_size, &y_size, 
                           &x_pos, &y_pos, &x_off, 
                           &y_off, &x_orig, &y_orig);

That part that was new to me was the [^.] part of 1023[^.] which says read up to 1023 characters and then the [...] says what characters I want to read. If you interested in only digits and dashes you would write [1234567890-]. The ^ is a modifier if used straight after the [ chaanges the meaning to read anything not in the []. Our expression can now be read as Read upto 1023 characters stopping when hit a .

This was all new to me but it appears to have been in C and hence C++ for quite a long time.

While the 1023 limit does worry me to much, if you are willing to go off standard then you can supply an a modifier that will allocate the string make it possible to read an unknown number of characters. Of course you have to remember to deallocate the char array when you are done.

That was another new discovery.


I am not suggesting this is the best way to parse csv in C or C++ as plenty of libraries exist. Actually you will probably have more fun using a different language to make a game. Actually use Godot, Unity or Unreal. I am just find I kind of enjoy writing in a subset of C++ that is very close to C. I quite like C really and may just port it to that.

I also enjoy Rust and many other programming languages so really just do what you want. After all if you are making small games it probably doesn't matter anyway.