如何获取从 GetPrivateProfileSection() 返回的单个字符串
How to obtain individual strings returned from GetPrivateProfileSection()
我一般用Java来编程。我只有 C++ 的基础知识。我目前正在使用 JNI 调用 Windows API GetPrivateProfileSection()。
我知道我必须编写一个 C++ 函数来执行此操作。我隐约熟悉如何做到这一点。我面临的问题是从 GetPrivateProfileSection() 返回的 C++ 字符串。
根据 Microsoft 文档,我了解到返回的字符串包含名称=值对,每个对由一个 NULL 字符分隔。姓氏=值对以 2 个 NULL 字符结尾。
我想做的是收集所有单独的 name=value 字符串并将它们放在一个数组中。我完全不知道如何使用 GetPrivateProfileSection() 返回的字符串执行此操作。我听说我需要做一些称为指针运算的事情,但我不知道如何做。
有人能帮帮我吗?谢谢!
将 INI 文件读取到 std::map 的代码如下所示:
LPTSTR str_settings = new TCHAR[bufferSize];
::GetPrivateProfileSection(_T("MySection"), str_settings , bufferSize, _T("MyIni.ini"));
std::map<std::string, std::string> settings; // map key -> value from ini file
std::string sett_string;
for (;*str_settings; str_settings += sett_string.length() + 1)
{
sett_string = str_settings;
size_t pos = sett_string.find('=');
std::string key;
std::string value;
if (pos == std::string::npos)
{
key = sett_string;
}
else
{
key.assign(sett_string.begin(), sett_string.begin() + pos);
value.assign(sett_string.begin() + pos + 1, sett_string.end());
}
settings[key] = value;
}
感谢您的回复。我在测试 C++ 程序中试验了您的源代码,效果很好。我注意到的一件事是 std::map class 与 Java 属性 class 非常相似。
我现在的目标是获取每个名称=值对并将它们背靠背连接到 C++ 字符串中,每个名称=值对由 \r\n 分隔。
经过一段时间的试验,我终于想出了以下似乎有效的代码:
void DoTest()
{
const int bufferSize = 1024;
LPTSTR str_settings = new TCHAR[bufferSize];
// Keep the original pointer. Need to delete later.
LPTSTR str_settings_original = str_settings;
// Another string to keep all name=value pairs back to back separated by \r\n.
LPTSTR str_settings_concatenated = new TCHAR[bufferSize];
// I keep getting crash until I tried the following :
// put a NULL character at the beginning of str_settings_concatenated.
str_settings_concatenated[0] = NULL;
::GetPrivateProfileSection(_T("MySection"), str_settings , bufferSize, _T("MyIni.ini"));
std::string sett_string;
for (;*str_settings; str_settings += sett_string.length() + 1)
{
sett_string = str_settings;
// str_settings effectively points to the next name=value pair
// and this is what I really want. I take advantage of this
// and pack them back-to-back into str_settings_concatenated
// separated by \r\n.
strcat(str_settings_concatenated, str_settings);
strcat(str_settings_concatenated, "\r\n");
}
delete str_settings_original;
str_settings_original = NULL;
delete str_settings_concatenated;
str_settings_concatenated = NULL;
}
要点:
- 我使用你的 for 循环构造来获取 str_settings 中的每个名称=值对。
- 在 for 循环的每次迭代中,str_settings 似乎总能得到下一个名称=值对,这对我来说效果很好,尽管老实说我不知道代码是如何工作的(但非常感谢你).
- 我创建了另一个 C++ 字符串来存储每个由 \r\n 分隔的名称=值对。我用 strcat() 来做这个。
- 我最初遇到了很多崩溃,str_settings_concatenated 似乎没有得到任何字符串。
- 我还记得,在 C++ 中,我们必须使用 new 对每个内存分配调用 delete。我试过了,但没有帮助。但是,我从一位朋友那里得到一些建议,告诉我应该在 str_settings_concatenated.
的开头放置一个 NULL 字符
代码现在运行良好。如果您不介意,能否也指出代码中存在的任何其他错误?
再次感谢您的帮助。
大卫.
P.S.: 很抱歉使用 post 的回答选项。由于字符限制,无法post将其作为评论。
我一般用Java来编程。我只有 C++ 的基础知识。我目前正在使用 JNI 调用 Windows API GetPrivateProfileSection()。
我知道我必须编写一个 C++ 函数来执行此操作。我隐约熟悉如何做到这一点。我面临的问题是从 GetPrivateProfileSection() 返回的 C++ 字符串。
根据 Microsoft 文档,我了解到返回的字符串包含名称=值对,每个对由一个 NULL 字符分隔。姓氏=值对以 2 个 NULL 字符结尾。
我想做的是收集所有单独的 name=value 字符串并将它们放在一个数组中。我完全不知道如何使用 GetPrivateProfileSection() 返回的字符串执行此操作。我听说我需要做一些称为指针运算的事情,但我不知道如何做。
有人能帮帮我吗?谢谢!
将 INI 文件读取到 std::map 的代码如下所示:
LPTSTR str_settings = new TCHAR[bufferSize];
::GetPrivateProfileSection(_T("MySection"), str_settings , bufferSize, _T("MyIni.ini"));
std::map<std::string, std::string> settings; // map key -> value from ini file
std::string sett_string;
for (;*str_settings; str_settings += sett_string.length() + 1)
{
sett_string = str_settings;
size_t pos = sett_string.find('=');
std::string key;
std::string value;
if (pos == std::string::npos)
{
key = sett_string;
}
else
{
key.assign(sett_string.begin(), sett_string.begin() + pos);
value.assign(sett_string.begin() + pos + 1, sett_string.end());
}
settings[key] = value;
}
感谢您的回复。我在测试 C++ 程序中试验了您的源代码,效果很好。我注意到的一件事是 std::map class 与 Java 属性 class 非常相似。
我现在的目标是获取每个名称=值对并将它们背靠背连接到 C++ 字符串中,每个名称=值对由 \r\n 分隔。
经过一段时间的试验,我终于想出了以下似乎有效的代码:
void DoTest()
{
const int bufferSize = 1024;
LPTSTR str_settings = new TCHAR[bufferSize];
// Keep the original pointer. Need to delete later.
LPTSTR str_settings_original = str_settings;
// Another string to keep all name=value pairs back to back separated by \r\n.
LPTSTR str_settings_concatenated = new TCHAR[bufferSize];
// I keep getting crash until I tried the following :
// put a NULL character at the beginning of str_settings_concatenated.
str_settings_concatenated[0] = NULL;
::GetPrivateProfileSection(_T("MySection"), str_settings , bufferSize, _T("MyIni.ini"));
std::string sett_string;
for (;*str_settings; str_settings += sett_string.length() + 1)
{
sett_string = str_settings;
// str_settings effectively points to the next name=value pair
// and this is what I really want. I take advantage of this
// and pack them back-to-back into str_settings_concatenated
// separated by \r\n.
strcat(str_settings_concatenated, str_settings);
strcat(str_settings_concatenated, "\r\n");
}
delete str_settings_original;
str_settings_original = NULL;
delete str_settings_concatenated;
str_settings_concatenated = NULL;
}
要点:
- 我使用你的 for 循环构造来获取 str_settings 中的每个名称=值对。
- 在 for 循环的每次迭代中,str_settings 似乎总能得到下一个名称=值对,这对我来说效果很好,尽管老实说我不知道代码是如何工作的(但非常感谢你).
- 我创建了另一个 C++ 字符串来存储每个由 \r\n 分隔的名称=值对。我用 strcat() 来做这个。
- 我最初遇到了很多崩溃,str_settings_concatenated 似乎没有得到任何字符串。
- 我还记得,在 C++ 中,我们必须使用 new 对每个内存分配调用 delete。我试过了,但没有帮助。但是,我从一位朋友那里得到一些建议,告诉我应该在 str_settings_concatenated. 的开头放置一个 NULL 字符
代码现在运行良好。如果您不介意,能否也指出代码中存在的任何其他错误?
再次感谢您的帮助。
大卫.
P.S.: 很抱歉使用 post 的回答选项。由于字符限制,无法post将其作为评论。