dataentry1 Ответов: 2

Функция записи справки для ввода логического и целочисленного или строкового значения в одну строку внутри INI-файла


Таким образом, в основном мой dll-файл читает файл configuration.ini, и я пытаюсь написать функцию, позволяющую мне поместить bool & Integer/atoi в одни и те же строки вместе с двумя разными типами STR char/atoi в одни и те же строки.

например

// значение виртуального ключа, значение виртуального ключа2
название здесь = vk_1, vk_2

// true / false, значение виртуального ключа
название здесь = true, vk_9
заголовок здесь = false, vk_p

пример целочисленной функции мне нужна помощь в получении значений и чтении из ini файла на нескольких строках

int Integer(LPSTR Value) {
	if (!_stricmp("A", Value)) return 'A';
	if (!_stricmp(":", Value)) return VK_OEM_1;
	if (!_stricmp("PAUSE", Value)) return VK_PAUSE;
	if (!_stricmp("VK_PAUSE", Value)) return VK_PAUSE;

return atoi(Value);
}


Что я уже пробовал:

я уже написал функцию для установки значений переменных int, позволяющую мне помещать столько значений int в одну строку, сколько я хочу

пример
// int 1, int 2, int 3, int 4, int 5
title here = 30, 4, 6, 99, 1
// bool variable, int 1
title here = off, 40

void setIntValue(LPSTR Value, INT Variable[])
{
	stringstream ss(Value);
	string word;
	int i = 0;

	while (getline(ss, word, ',')) {

		transform(word.begin(), word.end(), word.begin(), ::tolower);

		if (!_stricmp("on", word.c_str()) || !_stricmp("true", word.c_str()))
			word = "1";

		if (!_stricmp("off", word.c_str()) || !_stricmp("false", word.c_str()))
			word = "0";

		Variable[i] = stoi(word);
		if (ss.peek() == ',')
			ss.ignore();

		i++;
	}
}

Richard MacCutchan

Это действительно плохое дизайнерское решение. Библиотеки DLL должны быть автономными, чтобы они могли работать в любом пользовательском пространстве. Если какие-либо конкретные классы или функции нуждаются в определенных параметрах для управления своими операциями, то эти данные должны быть предоставлены exe-файлом, использующим функции dll.

2 Ответов

Рейтинг:
1

CPallini

На мой взгляд, используя INI файлы таким образом громоздки. Вероятно, вам нужен формат файла, более подходящий для хранения иерархически структурированных данных. Вы могли бы взглянуть на Сериализация-Википедия, свободная энциклопедия[^].


Рейтинг:
1

Jochen Arndt

Вы должны написать парсер, который разбивает каждую строку на ее элементы:
Заголовок, символ присвоения и разделенный запятыми список значений.

Вы можете, например, использовать strchr или string::find чтобы найти символ назначения и получить заголовок и параметры.

Затем извлеките несколько параметров с помощью strtok или сделайте это, как описано выше,но теперь используйте запятую. Затем удалите начальные и конечные (белые) пробелы из каждой подстроки и преобразуйте их в нижние.

Как только у вас есть один параметр, вы должны использовать таблицы поиска для определения типа и значения. При смешанном логическом и целочисленном значении я бы сначала проверил логические значения с помощью функции, возвращающей три состояния (не логическое, ложное и истинное):

int getBoolean(const char *s)
{
    if (0 == strcmp(s, "false") || 0 == strcmp(s, "no"))
        return 0;
    if (0 == strcmp(s, "true") || 0 == strcmp(s, "yes"))
        return 1;
    return -1;
}


Если вышеописанное не удается (возвращает -1), проверьте наличие целого числа:

typedef struct {
    const char *name;
    int value;
} lookup_t;

int getInteger(const char *s)
{
    static const lookup_t lookup[] = {
        { "pause", VK_PAUSE },
        // ...
        { NULL, -1 }
    };

    int i = 0;
    while (lookup[i].name)
    {
        if (0 == strcmp(s, lookup[i].name))
            break;
        i++;
    }
    return lookup[i].value;
}