PDA

View Full Version : read ini file content and save into array



cooper
11th March 2011, 01:19
Hi everyone,

In my program, i need to read an ini file to an array. here is my ini file:


[Config]
Number1=156
Number2=4

[StageNum]
1\cy1\7
1\cy1\2
1\cy1\5
1\cy1\2
1\cy1\3
1\cy1\0


in "StageNum", the first digit indicates all number in the same group (that's what i understand). "cy1" represents the name of array. the third digit is the value i want to read and save into an array.

i can read the single value in "config" successfully in my code, but i could not read "StageNum" into an array at all. Can anyone point out for me:

1) if the format of array setting is correct in ini file? if not, what is the right format?
2) if the format of array is correct in ini file, where does my code go wrong?

here is part of my code:


int arySize = m4Settings->beginReadArray("StageNum");
for (int vL = 0; vL < arySize; vL ++)
{
m4Settings->setArrayIndex(vL);
stageNo[vL] = m4Settings->value("cy1","0").toInt();
}
m4Settings->endArray();

when i step through the code, the "arySize" read 0 instead of 6.

Thanks in advance.

schnitzel
11th March 2011, 01:28
the documentation for QSettings shows forward slash '/', whereas you are using backslash '\'.

Documentation mentions:


QSettings always treats backslash as a special character and provides no API for reading or writing such entries.

The documentation shows an example of the correct format:
http://doc.qt.nokia.com/stable/qsettings.html#beginWriteArray

cooper
11th March 2011, 01:53
Hi schnitzel,

Thanks for your reply.
the file i am going to read is a .ini file, in the QSettings doc, it says:


Although backslash is a special character in INI files, most Windows applications don't escape backslashes (\) in file paths:


when i define my m4Settings, i was using:


m4Settings = new QSettings(QString(QApplication::applicationDirPath ()).append("/m4ini"), QSettings::IniFormat);


EDIT:

I have changed my [StageNum] content to use "/", but still, i got 0 for "arySize".

ChrisW67
11th March 2011, 04:12
Your syntax is all wrong. The first field in each entry is the index, the second the name of the value, and (you are completely missing this) the value itself comes after an equal sign. You are also missing the size attribute.

This defines a 6-element array called StageNum, where each element has a value called "cy1" (test.ini):


[Config]
Number1=156
Number2=4

[StageNum]
size = 6
0/cy1 = 7
1/cy1 = 2
2/cy1 = 5
3/cy1 = 2
4/cy1 = 3
5/cy1 = 0

and this will read it:


#include <QCoreApplication>
#include <QSettings>
#include <QDebug>


int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);

QSettings m4Settings("test.ini", QSettings::IniFormat);

int arySize = m4Settings.beginReadArray("StageNum");
qDebug() << "arySize =" << arySize;
for (int vL = 0; vL < arySize; vL ++)
{
m4Settings.setArrayIndex(vL);
qDebug()
<< "index =" << vL
<< "cy1 =" << m4Settings.value("cy1","0").toInt();
}
m4Settings.endArray();

return app.exec();
}

cooper
13th March 2011, 20:24
hi ChrisW67,

Thanks for your help. It's work.
I really appreciate that :)

EDIT:

but one more problem arises:
if my .ini file's content is


[StageNum]
size = 6

0/cy1 = 7
1/cy1 = 2
2/cy1 = 5
3/cy1 = 2
4/cy1 = 3
5/cy1 = 1

and my code is


int arySize = m4Settings->beginReadArray("StageNum");
for (int vL = 0; vL < arySize; vL ++)
{
m4Settings->setArrayIndex(vL);
cyNum[vL] = m4Settings->value("cy1", 0).toInt();
}
m4Settings->endArray();

the value of "cyNum" is:


cyNum[0] = 2
cyNum[1] = 5
cyNum[2] = 2
cyNum[3] = 3
cyNum[4] = 1
cyNum[5] = 0


I have step through the code, when vL = 0, cyNum[0] = 2...
I don't see where my code gets wrong. but why it read the value from second line.

then i tried:


int arySize = m4Settings->beginReadArray("StageNum");
for (int vL = 0; vL < arySize; vL ++)
{
m4Settings->setArrayIndex(vL - 1); // made a little change here
cyNum[vL] = m4Settings->value("cy1", 0).toInt();
}
m4Settings->endArray();

i got:


cyNum[0] = 2
cyNum[1] = 2
cyNum[2] = 5
cyNum[3] = 2
cyNum[4] = 3
cyNum[5] = 1


can anyone where i did it wrong, please?

cooper
14th March 2011, 02:07
I end up with changing my ini file and code as:
.ini


[StageNum]
size = 6
1/cy1 = 7
2/cy1 = 2
3/cy1 = 5
4/cy1 = 2
5/cy1 = 3
6/cy1 = 1

code:


int arySize = m4Settings->beginReadArray("StageNum");
for (int vL = 1; vL <= arySize; vL ++) // made a little change here
{
m4Settings->setArrayIndex(vL - 1); // made a little change here
cyNum[vL] = m4Settings->value("cy1", 0).toInt();
}
m4Settings->endArray();



cyNum[0] = 9076386
cyNum[1] = 7
cyNum[2] = 2
cyNum[3] = 5
cyNum[4] = 2
cyNum[5] = 3
cyNum[6] = 1


but i just cheat it. it is not what i really want. any good idea? :confused:

ChrisW67
14th March 2011, 04:07
You are reading index vL-1 and putting it into the array at index vL. What you see in the array at index 0 is whatever random rubbish was in the memory the array was allocated.

There's nothing I can see wrong with a round-trip through QSettings:


#include <QCoreApplication>
#include <QSettings>
#include <QDebug>

int data[] = { 3, 1, 4, 1, 5, 9 };

int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);

QSettings m4Settings("test.ini", QSettings::IniFormat);

// Write a test file
m4Settings.beginWriteArray("StageNum");
for (unsigned int i = 0; i < sizeof(data)/sizeof(int); ++i) {
m4Settings.setArrayIndex(i);
m4Settings.setValue("cy1", data[i]);
}
m4Settings.endArray();

// read it back
int arySize = m4Settings.beginReadArray("StageNum");
qDebug() << "arySize =" << arySize;
for (int vL = 0; vL < arySize; vL ++)
{
m4Settings.setArrayIndex(vL);
qDebug()
<< "index =" << vL
<< "cy1 =" << m4Settings.value("cy1", "0").toInt();
}
m4Settings.endArray();

return app.exec();
}

and this is what the file QSettings wrote looks like:


[StageNum]
1\cy1=3
2\cy1=1
3\cy1=4
4\cy1=1
5\cy1=5
6\cy1=9
size=6

Arrays are zero-based in C/C++, and everyone expects that, but it seems QSettings wants to behave differently :(



What are you ultimately trying to achieve with all of this? If you simply want to initialise an array there are easier ways to go about it.

cooper
14th March 2011, 19:56
If you simply want to initialise an array there are easier ways to go about it.


Yes, I just want to initialise an array by read from an ini file.
Do you have any good suggestion please?
I am still learning Qt and C++.
Thanks for your help.

ChrisW67
14th March 2011, 21:33
If you want to initialise an array or arrays (that can vary) from an INI file, or store and reload a variable array, then QSettings is as good a way as any (once you get past the quirks). You could just create a flat text file in your own format, e.g. one line per record with fields of your choosing, and read/write it with QTextStream.

If you just want to initialise an array with fixed values you can do what I do in the example above.