Чтение из INI-файла с дубликатами

0

У меня есть следующий файл INI:

    [Connection]
    Protocol=HTPP

    [Connection]
    Protocol=HTTPS

Есть ли способ сохранить два протокола в двух разных переменных? Я пытался написать:

    int a = GetPrivateProfileString(_T("Connection"), _T("Protocol"), _T(""), protocolChar, 32, path);
    int ab = GetPrivateProfileString(_T("Connection"), _T("Protocol"), _T(""), protocolChar2, 32, path);

И результат в том, что ProtocolChar, protocolChar2, хотя оба получают "HTTP".
Как я могу сохранить весь протокол в переменной по-разному?

  • 1
    Я уверен, что не с GetPrivateProfileString и др. Вам придется написать свой собственный анализатор INI-файлов, если по какой-то причине вы не можете избежать этого дублирования.
  • 1
    Единственное решение в этом случае - создать собственный анализатор INI-файлов?
Показать ещё 2 комментария
Теги:
visual-c++

1 ответ

0

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

[Connection0]
Protocol=HTPP

[Connection1]
Protocol=HTTPS

[Connection2]
Protocol=FTP

[Connection3]
Protocol=Telnet

При таком подходе вы можете выполнять итерацию по различным разделам Connection пока не попытаетесь загрузить ту, которая не существует.

#include <windows.h>
#include <iostream>
#include <sstream>

int main()
{
    for (DWORD i = 0, size = 1; size != 0; ++i)
    {
        std::ostringstream name;

        name << "Connection" << i;
        std::string protocol(100, 0);
        size = GetPrivateProfileStringA(
            name.str().c_str(),
            "Protocol",
            NULL,
            &protocol[0],
            protocol.size(),
            "./test1.ini");

        if (size != 0)
        {
            protocol.resize(size);
            std::cout
                << name.str().c_str()
                << ":protocol=" << protocol << "\n";
        }
    }
}

Другой способ состоит в том, чтобы иметь первичный раздел (т. Connections), который определяет список других разделов с уникальным именем. Преимущество этого заключается в том, что разделы намного проще в управлении, один удаляется и устраняет необходимость изменения порядка остальных разделов. В этом случае вы можете просто переписать содержимое Connections.

[Connections]
Connection0=HTTPConnection
Connection1=HTTPSConnection
Connection2=FTPConnection
Connection3=TelnetConnection

[HTTPConnection]
Protocol=HTPP

[HTTPSConnection]
Protocol=HTTPS

[FTPConnection]
Protocol=FTP

[TelnetConnection]
Protocol=Telnet

При таком подходе вы перебираете записи Connections а затем загружаете каждый отдельный раздел.

#include <windows.h>
#include <iostream>
#include <sstream>

int main()
{

    for (DWORD i = 0, size = 1; size != 0; ++i)
    {
        std::ostringstream name;

        name << "Connection" << i;
        std::string section(100, 0);
        size = GetPrivateProfileStringA(
            "Connections",
            name.str().c_str(),
            NULL,
            &section[0],
            section.size(),
            "./test1.ini");

        if (size != 0)
        {
            section.resize(size);
            std::string protocol(100, 0);
            size = GetPrivateProfileStringA(
                section.c_str(),
                "Protocol",
                NULL,
                &protocol[0],
                protocol.size(),
                "./test1.ini");
            if (size != 0)
            {
                protocol.resize(size);
                std::cout
                    << name.str().c_str()
                    << ":"
                    << section
                    << ":protocol=" << protocol << "\n";
            }
        }
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню