请教一个关于GetPrivateProfileString函数读取INI文件的问题

**最近有写一个运行再在Windows下的运维程序需求
运维程序exe通过读取ini文件匹配MAC地址来进行IP和计算机名的配置。我计划的实现思路逻辑如下:

目标Windows开机(IP及计算机名都是未配置状态) ---> 启动完成后运维程序exe运行 ---> 运维程序获取网卡MAC ---> 运维程序读取ini文件的所有MAC地址 ---> 将获取的网卡MAC地址与读取到的ini文件中的MAC进行匹配 ---> 匹配到条目则设置对应的IP和计算机名 --->完成退出

目前获取网卡MAC、配置IP、修改计算机名我都已经实现。问题在于MAC匹配上面。因为是INI文件,而非数据库表。假设MAC地址匹配了 aa-bb-cc-dd-ee-ff 如何让程序找到关联对应的IP和计算机名键值,即ip001键值和hostname001键值要跟mac001键值关联。是否还有其他的实现思路或INI文件设计方法,请有经验的师傅写个实例等等,谢谢~!!**

INI文件内容:

[config]
hostname001 = pc001
ip001 = 192.168.0.1
mac001 = aa-bb-cc-dd-ee-ff


hostname002 = pc002
ip002 = 192.168.0.2
mac002 = hh-ii-jj-kk-ll-mm


hostname003 = pc003
ip003 = 192.168.0.3
mac003 = nn-oo-pp-qq-rr-ss

建议用csv格式保存配置,这样可以用excel编辑,也可以用文本编辑器编辑,又方便程序读取

csv文件

pc001,192.168.0.1,aa-bb-cc-dd-ee-ff
pc002,192.168.0.2,hh-ii-jj-kk-ll-mm
pc003,192.168.0.3,nn-oo-pp-qq-rr-ss

读取代码

#include <stdio.h>
#include <string.h>

int main(){
    char linebuf[512];
    char hostname[64];
    char ip[64];
    char mac[64];
    char* line;
    int ret;
    char* findmac = "hh-ii-jj-kk-ll-mm";
    FILE* f = fopen("a.csv", "rb");
    if(!f){
        printf("file open error\n");
        return -1;
    }
    while(1){
        line = fgets(linebuf, 512, f);
        if(!line)break;
        if(*line == 0)continue;
        ret = sscanf(line, "%[^,],%[^,],%s", hostname, ip, mac);
        if(ret != 3)continue;
        if(strcmp(mac, findmac) != 0)continue;        
        printf("found hostname=%s, ip=%s\n", hostname, ip);
        fclose(f);
        return 0;        
    }
    printf("not found\n");
    fclose(f);
    return 1;
}

问题是啥

MFC读写ini配置文件(WritePrivateProfileString,GetPrivateProfileString,GetPrivateProfileInt)_三公子Tjq的博客-CSDN博客 本博文主要总结用MFC配置ini文件的用法,核心函数只有三个,分别为WritePrivateProfileString和GetPrivateProfileString和GetPrivateProfileInt。下面分别讲解这三个核心函数的功能和各个参数的意义。一、WritePrivateProfileString函数和GetPrivateProfileString函数功能和各个参数详细分析_getprivateprofilestring https://blog.csdn.net/naibozhuan3744/article/details/78783446?ops_request_misc=&request_id=&biz_id=102&utm_term=GetPrivateProfileString%E5%87%BD%E6%95%B0%E8%AF%BB%E5%8F%96INI&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-8-78783446.142^v92^controlT0_1&spm=1018.2226.3001.4187

可以试试用json的方式配置config,方便配置多个host的属性,然后用rapidjson解析出来;

{
  "host_array": [
    {
      "hostname": "pc001",
      "ip": "192.168.0.1",
      "mac": "aa-bb-cc-dd-ee-ff"
    },
    {
      "hostname": "pc002",
      "ip": "192.168.0.2",
      "mac": "hh-ii-jj-kk-ll-mm"
    },
    {
      "hostname": "pc003",
      "ip": "192.168.0.3",
      "mac": "nn-oo-pp-qq-rr-ss"
    }
  ]
}
#include <iostream>
#include <cstdio>
#include <unordered_map>
#include "./rapidjson/include/rapidjson/filereadstream.h"
#include "./rapidjson/include/rapidjson/document.h"
int main()
{
    rapidjson::Document docHandle;
    FILE* fileHandle = fopen("./config.json", "r");
    if (nullptr == fileHandle)
    {
        return -1;
    }
    fseek(fileHandle, 0, SEEK_END);
    const auto fileSize = ftell(fileHandle);
    fseek(fileHandle, 0, SEEK_SET);
    char* buffer = new char[fileSize];
    rapidjson::FileReadStream fileStream(fileHandle, buffer, fileSize);
    docHandle.ParseStream(fileStream);
    std::unordered_map<std::string, std::pair<std::string, std::string>> hostInfo;
    if (docHandle.HasMember("host_array") && docHandle["host_array"].IsArray())
    {
        const auto &hostArray = docHandle["host_array"].GetArray();
        for (size_t m = 0; m < hostArray.Size(); ++ m)
        {
            if (!hostArray[m].IsObject())
            {
                fclose(fileHandle);
                delete[] buffer;
                return -2;
            }
            const auto &valHost = hostArray[m].GetObject();
            auto hostName = valHost["hostname"].GetString();
            auto hostIp = valHost["ip"].GetString();
            auto hostMac = valHost["mac"].GetString();
            hostInfo.emplace(hostMac, std::make_pair(hostName, hostIp));
        }
    }
    std::string matchedMac = "aa-bb-cc-dd-ee-ff";
    if (hostInfo.end() != hostInfo.find(matchedMac))
    {
        hostInfo[matchedMac].first; // host name
        hostInfo[matchedMac].second; // host ip
    }
    fclose(fileHandle);
    delete[] buffer;
    return 0;
}

或者ini标识一下多个host,比如

[hostCnt]
count=3
[host_1]
hostname = pc001
ip = 192.168.0.1
mac = aa-bb-cc-dd-ee-ff
[host_2] 
hostname = pc002
ip = 192.168.0.2
mac = hh-ii-jj-kk-ll-mm
[host_3]
hostname = pc003
ip = 192.168.0.3
mac = nn-oo-pp-qq-rr-ss

不知道解决你的问题没有.

【以下回答由 GPT 生成】

根据您描述的问题,您需要使用GetPrivateProfileString函数从INI文件中读取与MAC地址匹配的IP和计算机名。以下是一个实现该功能的示例代码:

#include <iostream>
#include <Windows.h>
#include <string>

std::string getMACAddress()
{
    std::string macAddress;

    IP_ADAPTER_INFO adapterInfo[16];
    DWORD bufferSize = sizeof(adapterInfo);
    DWORD result = GetAdaptersInfo(adapterInfo, &bufferSize);

    PIP_ADAPTER_INFO adapter = adapterInfo;
    while (adapter)
    {
        macAddress = adapter->Address;
        if (!macAddress.empty())
            break;

        adapter = adapter->Next;
    }

    return macAddress;
}

std::string getValueFromINI(const std::string& section, const std::string& key, const std::string& filename)
{
    const int bufferSize = 255;
    char buffer[bufferSize];

    DWORD result = GetPrivateProfileString(section.c_str(), key.c_str(), "", buffer, bufferSize, filename.c_str());

    return std::string(buffer);
}

bool setValueToINI(const std::string& section, const std::string& key, const std::string& value, const std::string& filename)
{
    BOOL result = WritePrivateProfileString(section.c_str(), key.c_str(), value.c_str(), filename.c_str());
    return result != 0;
}

int main()
{
    std::string macAddress = getMACAddress();
    std::string iniFilename = "config.ini";

    std::string section = "config";
    std::string key = "mac001";
    std::string associatedIP = getValueFromINI(section, "ip001", iniFilename);
    std::string associatedHostname = getValueFromINI(section, "hostname001", iniFilename);

    if (macAddress == key)
    {
        // 找到匹配的MAC地址
        std::cout << "匹配到MAC地址,关联的IP地址:" << associatedIP << std::endl;
        std::cout << "关联的计算机名:" << associatedHostname << std::endl;

        // 进一步实现其他操作,比如配置IP和计算机名
        // ...
    }
    else
    {
        std::cout << "未找到对应的MAC地址" << std::endl;
    }

    return 0;
}

请注意,上述代码中使用了GetAdaptersInfo函数来获取网卡的MAC地址,GetPrivateProfileString函数从INI文件中读取键值。在main函数中,您可以通过调用getValueFromINI函数获取与MAC地址相关联的IP地址和计算机名,然后进行进一步的操作。

如果您需要在INI文件中添加、修改键值对,您可以使用setValueToINI函数实现。

请确保将config.ini替换为您实际使用的INI文件名。另外,该示例代码仅实现了部分功能,您可以根据需求进行进一步的开发和完善。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^