尝试从C ++中的ini文件中读取

时间:2019-06-20 06:08:08

标签: c++ winapi ini

所以我决定承担一种新的业余爱好,因为到目前为止我都负担不起PC的构建,我一直在尝试创建一个基于控制台的简单程序,该程序从ini文件中读取信息,但似乎无法读取它。根本没有,而是只输出默认值。和随机整数。

char* ReadINI(const char* sSection, const char* sSub, const char* sDefaultValue)
{
    char* sResult = new char[255];
    memset(szResult, 0x00, 255);
    GetPrivateProfileString(  sSection, sSub, sDefaultValue, sResult, 255, ".\\config.ini");
    return sResult;
}

int s_width = (int)ReadINI("CONFIGURATION", "WIN_WIDTH", 0);
int s_height = (int)ReadINI("CONFIGURATION", "WIN_HEIGHT", 0);
const char* value = ReadINI("CONFIGURATION", "WIN_NAME", "null");

这是我作为调试方式的输出,因此用户知道该应用已正确读取那里的设置。

std::cout << "Width: " << s_width << "\n"; // Displays random integer
std::cout << "Height: " << s_height << "\n"; // Displays random integer
std::cout << "Name: " << value << "\n "; // Displays null

这是我的.ini文件

[CONFIGURATION]
WIN_NAME="Notepad"
WIN_WIDTH="800"
WIN_HEIGHT="600"

2 个答案:

答案 0 :(得分:6)

请勿将相对路径传递给using System; namespace AgilePrinciplesCSharp.Chapter12.Listing12_2 { class Listing12_2 { static void Main(string[] args) { var door = new TimedDoor(); var client = new Client(door); client.TimeOut(); } } public interface ITimerClient { void TimeOut(); } // We force Door, and therefore (indirectly) TimedDoor, to inherit from TimerClient. public interface IDoor : ITimerClient { void Lock(); void Unlock(); bool IsDoorOpen(); } // Implementation of Door Interface with Timer functionality public class TimedDoor : IDoor { public bool IsDoorOpen() { return true; } public void Lock() { Console.WriteLine("Door Locked"); } public void TimeOut() { var timer = new Timer(); timer.Register(5, this); Console.WriteLine("Timeout! Door left open for so long"); } public void Unlock() { Console.WriteLine("Door Unlocked"); } } // Timer class can use an object of TimerClient public class Timer { public void Register(int timeout, ITimerClient client) { /* CODE */ } } // Client uses Door Interface without depending upon any particular implementation of Door public class Client { IDoor door; public Client(IDoor door) { this.door = door; } public void TimeOut() { door.TimeOut(); } } } 函数,而需要传递绝对路径。 PrivateProfile API将相对路径解释为相对于Windows安装文件夹,而不是相对于调用进程的当前工作目录,这与您期望的相对。这是documented behavior

  

lpFileName

     

初始化文件的名称。如果此参数不包含文件的完整路径,则系统将在Windows目录中搜索文件。

您实际上并不是从(Get|Write)PrivateProfile...文件中读取数据,因此可以获取指定的默认值。

您无法将.ini指针强制转换为char*来获取所需的数值。您正在打印int所指向的内存地址,而不是字符串表示的整数值。您需要解析字符串,例如使用Win32 char*或C StrToInt()或标准C ++库sscanf()std::atoi()std::stoi()。在这种情况下,更好的解决方案是改用GetPrivateProfileInt(),然后让API为您进行解析。

您还会泄漏分配的std::istringstream字符串。您应该改用char*,并让标准C ++库为您处理内存管理。

话虽如此,请尝试以下类似操作:

std::string

答案 1 :(得分:-2)

变量sResult在函数范围内,它将在堆栈中 从函数返回后,它就会被销毁。

使用malloc或从堆中分配内存以在函数外部获取值。

这有效,将ini放在当前工作目录中即可。

    char* sResult = new char[255];
    char* ReadINI(const char* sSection, const char* sSub, const char* sDefaultValue)
    {
        memset(sResult, 0x00, 255);
        GetPrivateProfileString(sSection, sSub, sDefaultValue, sResult, 255, ".\\config.ini");
        return sResult;
    }

...

    char pwd[MAX_PATH];
    GetCurrentDirectory(MAX_PATH, pwd);
    MessageBox(NULL, pwd, pwd, 0);
    int s_width = atoi(ReadINI("CONFIGURATION", "WIN_WIDTH", 0));
    int s_height = atoi(ReadINI("CONFIGURATION", "WIN_HEIGHT", 0));
    const char* value = ReadINI("CONFIGURATION", "WIN_NAME", "null");
    std::cout << "Width: " << s_width << "\n"; 
    std::cout << "Height: " << s_height << "\n";
    std::cout << "Name: " << value << "\n ";