所以我决定承担一种新的业余爱好,因为到目前为止我都负担不起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"
答案 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在函数范围内,它将在堆栈中 从函数返回后,它就会被销毁。
这有效,将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 ";