Возможно, этот мост, вероятно, был пройден много раз и разными способами ... читая простой текстовый файл .conf и воздействуя на его записи.
В моем случае, формат файла прост .. aпоследовательность токенов и назначений, например:
token_name_1 value
с символом табуляции в качестве разделителя полей и окончанием строки Unix для каждой записи.
Файл .conf напрямую изменяет определенныеконфигурации программы, все они хранятся в единой структуре.Переменные типов Integer, float, char [] и * char представлены в структуре.
Быстрый, но скучный подход включает, например:
if (strcasecmp(token,"token_name_1")==0)
token_name_1=value;
Но я определил, что этобыло бы приятно сделать дело в хорошей тесной петле.В C.
Таким образом, казалось, лучше всего построить массив, который обеспечивает указатели для каждой из переменных структуры, которые я хочу раскрыть;другой, который предоставляет имя переменной;и третий, который описывает тип хранимых данных и требуемое значение по умолчанию.
Они выглядят так:
const char* allowed_tokens[] =
{
"loglevel",
"debugecho",
"errorSqlDisable",
"ClearErrorDbOnExit",
"\0" // terminates list
}
int *varpointers[] =
{
&appinfo.nLogLevel,
&appinfo.debugEcho,
&appinfo.OWFSLogLevel,
&appinfo.OWFSLogEchoToDisplay,
0 // terminates list
};
char *varDatatypes_defaults[] =
{
"I|6", // for LOG_INFO
"B|false",
"I|0",
"B|true",
"\0" // terminates list
};
Цикл выглядит следующим образом (псевдокод):
row=0;
while (read a line of the .conf file into cLine)
{
get the token_name and value from cLine
check if allowed_tokens[row]==0 and if true, exit the loop
// example cLine= "debugecho false"
find match to "debugecho" in allowed_tokens. This provides an offset into varpointers and varDatatypes.
get the default data type and default value tokens from varDattypes_defaults[row]
Do the assignment. For example, if the data type=="I":
*varpointers[row]=atoi(value);
++row;
}
Этот метод работает отлично, но есть две проблемы.
- Было бы предпочтительнее объединить три массива в один массив.Есть ли здесь лучшая практика?
- Массив указателей (varpointers []) определяется как * int.Я сделал так, как я хочу, чтобы он держал указатели.Однако, если указанная переменная не является целочисленным типом данных, предупреждение: инициируется инициализация из несовместимого типа указателя.Конечно, char * и int * нельзя смешивать ... так как иначе это можно сделать так, чтобы использовался один массив указателей?
Я понимаю, что могу делать все это в c ++.Эта роскошь на данный момент не вариант.