c++使用GetPrivateProfileString读取配置文件参数

c++ read config file parameters using GetPrivateProfileString

本文关键字:配置文件 参数 读取 GetPrivateProfileString 使用 c++      更新时间:2023-10-16

我在C++、Visual Studio 2012中有一个win32控制台应用程序。我无法从ini文件中获取config参数。我尝试了文件路径的不同可能性,比如将.ini文件放在源文件夹中,将完整路径写入is,将生成的.exe文件放在文件夹中。在任何情况下,执行.exe文件后控制台上的输出对于字符串都是0或(null)。我做错了什么?如何读取参数?

v1:
LPCTSTR path = L".\config.ini";
TCHAR protocolChar[32];
int port = GetPrivateProfileString(_T("PORT"), _T("SETTINGS"), _T(""), protocolChar, 32, path);
printf("***%d***n", port);
v2:
int port = GetPrivateProfileInt(_T("PORT"), _T("SETTINGS"), 0, _T("config.ini"));

config.ini包含:

[SETTINGS]
USER_NUM_MAX = 256  ; Maximum number of users
PORT = 8080; 

Oups,在Windows下点击ini文件并不是那么容易。在两次尝试(v1和v2)中,您都会在当前目录中查找文件,然后在Windows目录中查找,但不会在可执行文件所在的目录中查找。

简单的方法是将所有ini文件放在Windows目录下。如果你发现清洁器有ini文件和exe文件,你还有更多的工作要做:

  • 查找可执行文件的完整路径
  • exe端替换为ini
  • 使用该完整路径可以访问您的私人ini文件

要获得可执行文件的名称,只需使用带有NULL HMODULE:的GetModuleFileName

LPCTSTR getExecPath() {
    DWORD len = 64;
    for (;;) {
        LPTSTR fileName = new TCHAR[len];
        if (len == ::GetModuleFileName(NULL, fileName, len)) {
            delete fileName;
            len *= 2;
        }
        else {
            return fileName;
        }
    }
}

或者如果您更喜欢直接获取ini文件名:

LPCTSTR getIniName() {
    DWORD len = 4;
    for (;;) {
        LPTSTR fileName = new TCHAR[len];
        if (len == ::GetModuleFileName(NULL, fileName, len)) {
            delete fileName;
            len *= 2;
        }
        else {
            ::lstrcpy(fileName + lstrlen(fileName) - 3, "ini");
            return fileName;
        }
    }
}

并且在完成时不要忘记删除文件名,因为它被分配了新的。。。

按注释编辑:

作为参考,windows目录可能取决于windows版本。但是它总是可以被API函数GetWindowsDirectory检索。参考页面摘录:

UINT WINAPI GetWindowsDirectory(
  _Out_  LPTSTR lpBuffer,
  _In_   UINT uSize
);

参数

  • lpBuffer [out]指向接收路径的缓冲区的指针。除非Windows目录是根目录,否则此路径不会以反斜杠结束。例如,如果驱动器C上的Windows目录名为Windows,则此函数检索到的Windows目录的路径为C:\Windows。如果系统安装在驱动器C的根目录中,则检索到的路径为C:
  • uSize [in]lpBuffer参数指定的缓冲区的最大大小,以TCHAR为单位。该值应设置为MAX_PATH

返回值

如果函数成功,返回值是复制到缓冲区的字符串的长度,以TCHAR为单位,不包括终止的null字符

如果长度大于缓冲区的大小,则返回值为保存路径所需的缓冲区大小

如果函数失败,则返回值为零。若要获取扩展的错误信息,请调用GetLastError*

当我从VS2010更新到VS2012时,我遇到了这个问题。

在VS2010上,我只是用.ini文件的文件名作为lpFileName的参数来调用函数(请参阅MSDN文档)。

这不再适用于VS 2012,所以我改走这样的完整路径:

char directoryPath[MAX_PATH];
char readParameter[MAX_STR_LEN];
GetCurrentDirectory( directoryPath, MAX_PATH );
string directoryPathAsString(directoryPath);
directoryPathAsString = directoryPathAsString + "\" + filename;
GetPrivateProfileString("section","parameter","0",readParameter,MAX_STR_LEN, directoryPathAsString.c_str());