There are two ways to read arrays with MiniINI. The first is to read from tags with multiple values. The other is to read from series of numbered tags.

Reading from multi value tags is both faster (parsing wise), and such tags take less space. Series of tags might be more practical in some cases, though. Both ways are explained here.

ReadMultiXXX

MiniINI parses commas as value separators, so a value with commas will be parsed as an array. This also means a single value can't contain commas. You can read from multi value tags using INISection methods ReadMultiString, ReadMultiInt, ReadMultiFloat and ReadMultiBool. These methods have versions to read to plain C arrays and STL vectors. Like the ReadXXX methods, they work similarly to each other.

Non-STL versions take tag name, buffer to read to and buffer capacity, i.e. how many values of read type the buffer can hold. They return number of values read (zero if the tag doesn't exist). Tag name must be a zero terminated string and the buffer must have at least specified capacity. ReadMultiXXX will read at most as many values as specified capacity, even if there are more in the file. ReadMultiString, like ReadString, only writes pointers (C strings) to the buffer, so you have to copy the data if you want to use it after the INIFile is deleted.

STL versions are a bit simpler: Like STL ReadXXX, tag name is a C++ string, and the buffer is a vector. There is no need to pass capacity as vector can enlarge as needed. Like the non-STL version, number of read values is returned.

Note: if a value has incorrect type (e.g. "abc" can't be parsed as int when using ReadInt), only values before it are read.

Example:

If we have a file containing a multi value tag like this:

;section header, other tags
;...
images=01.png,02.png,03.png
;...
;other ini data

We can read to array like this:

Non-STL version:

//load a file, get section...
unsigned cap = 16;
const char** buf = new const char* [cap];
unsigned imgcount = section->ReadMultiString("images", buf, cap);
if(!imgcount)
    std::cout << "ERROR: Could not find multi value tag images=";
for(unsigned image = 0; image < imgcount; ++image)
    std::cout << buf[image] << std::endl;
//more code and deinitialization - don't forget to delete buf !

STL version:

//don't forget to include <vector>
//load a file, get section...
vector<std::string> buf;
std::string name = "images";
unsigned imgcount = section->ReadMultiString(name, buf);
if(!imgcount)
    std::cout << "ERROR: Could not find multi value tag images=";
for(unsigned image = 0; image < imgcount; ++image)
    std::cout << buf[image] << std::endl;
//more code and deinitialization

MultiValSize

In above examples using non-STL methods, we allocate a fixed space of memory without knowing size needed to store all values. INISection method MultiValSize can determine this size. It takes a tag name, and returns number of values in that tag (zero if the tag doesn't exist). Again, the tag name must be a zero terminated string.

Non-STL example with MultiValSize:

//load a file, get section...
unsigned cap = section->MultiValSize("images");
const char** buf = new const char* [cap];
unsigned imgcount = section->ReadMultiString("images", buf, cap);
if(!imgcount)
    std::cout << "ERROR: Could not find multi value tag images=";
for(unsigned image = 0; image < imgcount; ++image)
    std::cout << buf[image] << std::endl;
//more code and deinitialization - don't forget to delete buf !

Now you should know all you need to load arrays from multi value tags. If you don't want to learn about how to read arrays from series of numbered tags, you can skip the rest of the tutorial.

ReadXXXs

MiniINI can also read arrays from series of numbered tags, such as:

img1=01.png
img2=02.png
img3=03.png
...
img10=10.png

Indices in INI files start at 1, not 0 like C/C++ arrays. Reading arrays this way is almost the same as multi value tags, but instead of ReadMultiXXX and MultiValSize you use ReadStrings, ReadInts, ReadFloats, ReadBools and ArraySize. The first argument of ReadXXXs is a base name of tags in the sequence, i.e. "img" in the above example. Other arguments are identical.

If you want just plain numbers without a base name, you can use empty string (""), to read from a sequence like this:

1=01.png
2=02.png
3=03.png

If an index is missing (e.g. you have img1 and img3, but not img2), only values before that index are read. Same thing happens if a value can't be parsed as the expected type.

Example:

If a file contains this:

;section header, other tags
;...
img1=01.png
img2=02.png
img3=03.png
;...
;other data

We can read it using ReadXXXs like this:

Non-STL version:

//load a file, get section...
unsigned cap = 16;
const char** buf = new const char* [cap];
unsigned imgcount = section->ReadStrings("img", buf, cap);
if(!imgcount)
    std::cout << "ERROR: Could not find multi value tag images=";
for(unsigned image = 0; image < imgcount; ++image)
    std::cout << buf[image] << std::endl;
//more code and deinitialization - don't forget to delete buf !

STL version:

//don't forget to include <vector>
//load a file, get section...
vector<std::string> buf;
std::string name = "img";
unsigned imgcount = section->ReadStrings(name, buf);
if(!imgcount)
    std::cout << "ERROR: Could not find multi value tag images=";
for(unsigned image = 0; image < imgcount; ++image)
    std::cout << buf[image] << std::endl;
//more code and deinitialization

ArraySize is similar to MultiValSize, but it determines number of tags with given base name.

Non-STL version using ArraySize to determine space to allocate:

//load a file, get section...
//...
unsigned cap = section->ArraySize("img");
const char** buf = new const char* [cap];
unsigned imgcount = section->ReadStrings("img", buf, cap);
if(!imgcount)
    std::cout << "ERROR: Could not find tag array img";
for(unsigned image = 0; image < imgcount; ++image)
    std::cout << buf[image] << std::endl;
//more code and deinitialization - don't forget to delete buf !


Last update: 07-07-2010