WritePrivateProfileString在main中工作但不在函数中

时间:2018-04-03 00:03:47

标签: c++ parsing ini

我正在尝试将WritePrivateProfileString和GetPrivateProfileInt用于.ini解析器。

当我将下面的代码放入main()或类构造函数中时,它适用于写作和阅读。

但是,当我创建用于写入和读取的函数,并调用main()中的函数时,没有任何反应,尽管如果我要求函数运行它们将会cout运行。

这是我为了证明这一点而编写的测试程序:

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

#define CStringify(x) std::to_string(x).c_str()

int testvar = 12;
int returntestvar = 0;
std::fstream config;

std::string configstring = ".//config.ini";

int main()
{   
    WriteINI();
    ReadINI();
    std::cout << returntestvar << std::endl;
    getchar();
}

void WriteINI()
{
    config.open("config.ini", std::ios::app);
    WritePrivateProfileString("Test", "Test1", CStringify(testvar), configstring.c_str());
}

 void ReadINI()
{
    config.open("config.ini", std::ios::app);
    returntestvar = GetPrivateProfileInt("Test", "Test1", 0, configstring.c_str());
}

上面的代码创建并编辑了.ini文件,正如预期的那样。

但是,如果我将代码移到一个类中,它将不再有效。

的main.cpp

#include <iostream>
#include <Windows.h>
#include <fstream>
#include <string>
#include "INIClassTest.h"

extern INIParser* Parse;

int main()
{   
    Parse->WriteINI();
    Parse->ReadINI();
    std::cout << Parse->returntestvar << std::endl;
    getchar();
}

INIClassTest.h

#pragma once
#include <fstream>
#include <string>
#include <Windows.h>

#define CStringify(x) std::to_string(x).c_str()

class INIParser
{
public:
    INIParser();
    void WriteINI();
    void ReadINI();

    int testvar;
    int returntestvar;
    std::fstream config;
    std::string configstring;

};

extern INIParser* Parse;

INIClassTest.cpp

#include "INIClassTest.h"
#include <iostream>

INIParser* Parse = new INIParser();

INIParser::INIParser()
{
    returntestvar = 0;
    testvar = 18;
    std::string configstring = ".//config.ini";
}

void INIParser::WriteINI()
{
    config.open("config.ini", std::ios::app);
    WritePrivateProfileString("Test", "Test1", CStringify(testvar), configstring.c_str());
}

void INIParser::ReadINI()
{
    config.open("config.ini", std::ios::app);
    returntestvar = GetPrivateProfileInt("Test", "Test1", 0, configstring.c_str());
}

上面的代码会创建一个.ini文件,但它不会对其进行编辑或返回任何内容。

1 个答案:

答案 0 :(得分:0)

您根本不应该使用fstream来手动创建/打开INI文件。 WritePrivateProfileString()GetPrivateProfileInt()为您处理。

另外,如果你阅读他们的文档,你会发现你不应该使用INI文件的相对路径,否则文件将相对于Windows安装文件夹,而不是你的app文件夹。所以,你可能正在读/写INI文件,而不是你想要的地方。如果您希望INI文件相对于应用程序的文件夹,则需要检索应用程序文件夹 1 的路径并将INI文件名附加到其中。

1 :尽管如此,这确实不是一个好主意。根据您安装应用程序的位置,用户可能没有该文件夹的写入权限。您应该使用SHGetFolderPath()SHGetKnownFolderPath()来获取用户的本地%AppData%文件夹,然后在其中创建自己的子文件夹,然后在该子文件夹中创建INI文件。

请改为尝试:

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

#define CStringify(x) std::to_string(x).c_str()

std::string GetAppFolder();
std::string GetINIPath();
void WriteINI();
void ReadINI();

int testvar = 12;
int returntestvar = 0;
std::string configstring = GetINIPath();

int main()
{   
    WriteINI();
    ReadINI();
    std::cout << returntestvar << std::endl;    
    std::cin.get();
    return 0;
}

std::string GetAppFolder()
{
    char szFileName[MAX_PATH];
    DWORD len = GetModuleFileName(NULL, szFileName, MAX_PATH);
    std::string result(szFileName, len);
    std::string::size_type pos = result.find_last_of("\\/");
    result.resize(pos+1);
    return result;
}

std::string GetINIPath()
{
    return GetAppFolder() + "config.ini";
}

void WriteINI()
{
    WritePrivateProfileString("Test", "Test1", CStringify(testvar), configstring.c_str());
}

void ReadINI()
{
    returntestvar = GetPrivateProfileInt("Test", "Test1", 0, configstring.c_str());
}

您的INIParser类失败的主要原因是您的构造函数将INI文件路径存储在名为configstring的局部变量中,而不是在名为configstring的类成员中。因此,在调用WriteINI()ReadINI()时,类成员为空。

请改为尝试:

的main.cpp

#include <iostream>
#include "INIClassTest.h"

int main()
{   
    Parse.WriteINI();
    Parse.ReadINI();
    std::cout << Parse.returntestvar << std::endl;
    std::cin.get();
    return 0;
}

INIClassTest.h

#pragma once
#include <string>

class INIParser
{
public:
    INIParser();
    void WriteINI();
    void ReadINI();

    int testvar;
    int returntestvar;
    std::string configstring;
};

extern INIParser Parse;

INIClassTest.cpp

#include <Windows.h>
#include "INIClassTest.h"
#include <string>

#define CStringify(x) std::to_string(x).c_str()

INIParser Parse;

static std::string GetAppFolder()
{
    char szFileName[MAX_PATH];
    DWORD len = GetModuleFileName(NULL, szFileName, MAX_PATH);
    std::string result(szFileName, len);
    std::string::size_type pos = result.find_last_of("\\/");
    result.resize(pos+1);
    return result;
}

static std::string GetINIPath()
{
    return GetAppFolder() + "config.ini";
}

INIParser::INIParser()
{
    returntestvar = 0;
    testvar = 18;
    configstring = GetINIPath();
}

void INIParser::WriteINI()
{
    WritePrivateProfileString("Test", "Test1", CStringify(testvar), configstring.c_str());
}

void INIParser::ReadINI()
{
    returntestvar = GetPrivateProfileInt("Test", "Test1", 0, configstring.c_str());
}