PDA

View Full Version : How to automatically detect the type of a key in a ini file QSettings



dean76
15th January 2013, 16:52
Hi everyone,

In my program I have to set a variable by reading a ini file, the problem is the variable can be either string or double, and I need to assign them to the correct variable type.

To be more precise, my ini file will look like this:

[DATA]
link0 theta=t1
link0 alfa=a1

link1 theta=0.0
link1 alfa=a2

link3 theta=0
link3 alfa=90

The variables "theta" and "alpha" can be defined as a string ("a1", "t1") or as a double ("0.0","90").

if I do something like this:



settings.beginGroup("DATA");
const QStringList childKeys = settings.childKeys();

foreach (const QString &childKey, childKeys)
{
std::cout << settings.value(childKey).type() << std::endl;
std::cout << settings.value(childKey).toString().toStdString() << std::endl;
}
settings.endGroup();



the type() function always return the value=10, which in QVariant enum Type means "string", even when the variable is a number (as in the case of "theta" of link1 =0.0 )

What I need to do is, if the data in the ini File is a number store it in a double variable, if is a string then store it in a string variable. For example, in my example of ini File:
the variable "theta" of link0 should be stored in a string--> std::string a= settings.value(childKey).toString().toStdString()
the variable "theta" of link1 should be stored in a double--> double b= settings.value(childKey).toDouble()

This is:


foreach (const QString &childKey, childKeys)
{
std::cout << settings.value(childKey).type() << std::endl;
if (type is number) //<<<<<<<<<<<<<<<<<<<<<< How to detect the correct type here?
double b= settings.value(childKey).toDouble()
else
std::string a= settings.value(childKey).toString().toStdString()
}



I have in mind to treat all the variables as a string and detect if in the string there's any of the characters "a","b","c",...,"x","y","z","A","B",...,"Z", if there is any of them, then saved in a string variable, else is a number. However, that sounds to complicated. Is that possible in a simple way?

I Hope the question is not to confusing :).

Thanks,

anda_skoa
15th January 2013, 17:12
You could try


if (settings.value(key).canConvert<double>()) // double


or use the boolean argument of toDouble() to check for conversion success


bool ok = false;
double d = settings.value(key).toDouble( &ok );
if (!ok) // not a double


Cheers,
_

dean76
16th January 2013, 11:15
Thanks for the fast reply!

I tried both and the second option is the best ;). Just to summarize:
Given the next ini File:

[GENERALCONFIG]
DOF=2
[DH]
link0 theta= 0
link0 d= d1
link0 a = 34.456768996
link0 alpha = alpha1

link1 theta= 90
link1 d= d2
link1 a = a2
link1 alpha = alpha2

Where the variables can be either strings or doubles, the solution to store each variable in the correct data type is:



settings.beginGroup("DH");
const QStringList childKeys = settings.childKeys();

std::vector<double> vDouble;
std::vector<std::string> vString;

foreach (const QString &childKey, childKeys)
{
bool ok = false;
double d = settings.value(childKey).toDouble(&ok);
if (ok) // a double
{
vDouble.push_back(d);
std::cout << "Is a Double" << d << std::endl;
}
else
{
std::string temp;
temp=settings.value(childKey).toString().toStdStri ng();
vString.push_back(temp);
std::cout << "Is a String: " << temp << std::endl;
}
}


This is assuming that int and doubles need to be stored in the same variable type (double).

Thanks!