You have less worries
Yes, the sky is blue

Cracking an INI file with a jackhammer

26 February 2009, by Ben    13 comments

INI File SnippetAll I was after was a simple .INI file reader in C or C++. You know, to parse [section] and name=value lines for config files. We needed it for an embedded Linux project, so it had to be small, portable and only dependent on the C and C++ standard libraries.

Maybe it’s my embedded background that makes me defensive about my mild case of Not-Invented-Here syndrome. Then again, perhaps I’m in good company.

But surely there are tons of INI parsing libraries around, right? Well, kind of.

I found no fewer than 15 in under an hour. But why is it that things like this are either way off the mark (bloated or non-portable) or they’re very close, but just not quite what you want?

Below is the list of INI file readers that I found, from bad to better. Some of the ones that weren’t for me might well suit your application, so treat this as something of a non-exhaustive list of INI file readers:

Not for me

Half way there

So very close

INI Not Invented Here (INIH)

Of course, in the time it took to investigate all these, I could have easily written my own. And, being unable to help myself, I did. :-) So I present you with my own offering: INI Not Invented Here, a.k.a. INIH or simply ini.h.

It contains a small C function, ini_parse(), that parses an INI file and executes the given callback function for each name=value pair parsed (think SAX).

The reason I used the callback style is so you don’t have to load the whole file into memory if you don’t need to — good for embedded systems. Plus, I wanted to be able to use the parser easily in C, but not implement a dictionary-like structure in C.

For a more user-friendly, lookup style API if you’re using C++, I’ve wrapped ini_parse() in a class called INIReader, which has Get() and GetInteger() methods (all I needed). And it’s easy to sub-class INIReader if you need fancier GetXYZ() functions.

Show us the code

UPDATE: I’ve moved the code from here to its own Google Code project at http://code.google.com/p/inih/ — enjoy!

13 comments and pings (oldest first)

paavels 26 Feb 2009, 23:03 link

Thanks for inventing the bicycle.

Btw wxWidgets does it rather than perfect

http://docs.wxwidgets.org/stable/wx_wxconfigbase.html#wxconfigbase

danijel 27 Feb 2009, 04:34 link

However useless the above comment is, he does have a point. You see, you were complaining on how difficult it is to find the right library for your program out of so many available on the internet and then you go ahead and make another one yourself. It is very likely that someone else who stumbles upon your code will have the same sentiment as you did with the others…

Eoin 27 Feb 2009, 05:01 link

Seems quite simple, straighforward and portable. Bravo!

Alvaro 27 Feb 2009, 06:19 link

I my own little utils library I have support for this. Using it looks like this:

IniFile config("config.ini");
config.section("user");
String email = config["email"];

or with section/variable :

IniFile config("config.ini");
String username = config["user/name"];

or all in one line, without creating a config object:

int protocol = IniFile("config.ini")["protocol/version"];
FPM 27 Feb 2009, 07:20 link

I used crack INI files with jackhammer back when I was a homeless rodeo clown but not any more. Now I am a world class magician !

Ben 27 Feb 2009, 10:06 link

Hi Alvaro, that’s quite neat — great use of operator overloading. Out of interest, I don’t suppose you could post the code somewhere?

Danijel, you’re right about someone else not finding my code good for their purposes. I guess that’s part of the attraction of NIH — you get exactly what you want, no more, no less.

Ping: Small regex libraries 27 Feb 2009, 10:55 link

[...] I’m on the lookout for small libraries anyway, I thought I’d also post a list of a few regular expression libraries I’ve found [...]

[...] The Brush Blog :: Cracking an INI file with a jackhammer (tags: cpp) [...]

Ben 28 Feb 2009, 14:22 link

For reference, here’s a simple C-based example for using ini_parse() to parse your program’s config file:

/* Simple INIH example */

#include "ini.h"
#include <string.h>

typedef struct {
    char* name;
    int age;
} config;

int config_handler(void* user, const char* section,
                   const char* name, const char* value)
{
    config* cfg = (config*)user;

    if (stricmp(section, "user") == 0) {
        if (stricmp(name, "name") == 0)
            cfg->name = strdup(value);
        else if (stricmp(name, "age") == 0)
            cfg->age = atoi(value);
    }
}

void run_program(config* cfg)
{
    printf("%s is %d years old\n", cfg->name, cfg->age);
}

void main()
{
    config cfg = {"Anon Y Mous", 42};  /* Default config */

    ini_parse("config.ini", config_handler, &cfg);
    run_program(&cfg);
}
Ludvik Jerabek 28 Apr 2009, 02:06 link

C++ class, but uses loads of non-portable MFC helper classes. It’s funny you mention it’s non portable which is 100% correct. I wrote one which was in standard C++ and STL if there is still interest in this let me know.

Anon 6 May 2009, 00:59 link

I was looking for exactly this. If not you I would have written it. Extremely lightweight yet economic. Will use thx!

Ludvik Jerabek 20 May 2009, 08:17 link

Here is the text for that Ansi C++ code [snipped]. I will also update the code project page to have this available.

Updated project is located at:

http://www.codeproject.com/KB/cpp/CIniFile.aspx

Ri 22 May 2009, 22:42 link

To be honest, I’d rather re-invent the wheel as well (only way to know where your code’s been and who touched it :P ) but since I don’t have enough experience yet – thank you for writing code that even I can follow and use :)

Add a comment

We reserve the right to edit or remove your comment if it’s spammy, offensive, unintelligible, or if you don’t give a valid email address. :-)

We’ll never share your email address.