我想这是一种类似 INI 的语法,但没有部分,要解析它,请执行以下操作。
在您将用于解析文件的类的构造函数(例如)中:
- 创建一个
Dictionary<string, string>
,您将在那里保留解析的值(为键指定一个不区分大小写的比较器)。
- 阅读文件的每一行,跳过空白行(如果你想支持它,也可以跳过注释行)。
- 在每个字符串行中搜索第一个“=”字符。左边的部分是选项的名称,右边的部分是值。
- 将它们保存在字典中。
在GetValue()
方法中这样做:
- 在字典中搜索给定的键并返回它。
- 如果没有具有给定值的任何键,则只需返回默认值。
这是一个简单 INI 解析器的可能实现(如果您不需要节名称,只需为其传递一个空字符串)。
using namespace System;
using namespace System::Text;
using namespace System::IO;
using namespace System::Globalization;
using namespace System::Collections::Generic;
namespace Testy
{
ref class IniParser
{
public:
IniParser()
{
_values = gcnew Dictionary<String^, Dictionary<String^, String^>^>(
StringComparer::InvariantCultureIgnoreCase);
}
IniParser(String^ path)
{
_values = gcnew Dictionary<String^, Dictionary<String^, String^>^>(
StringComparer::InvariantCultureIgnoreCase);
Load(path);
}
void Load(String^ path)
{
String^ currentSection = "";
for each (String^ line in File::ReadAllLines(path))
{
if (String::IsNullOrWhiteSpace(line))
continue;
if (line->StartsWith(L";", StringComparison::InvariantCultureIgnoreCase))
continue;
if (line->StartsWith(L"[", StringComparison::InvariantCultureIgnoreCase) && line->EndsWith(L"]", StringComparison::InvariantCultureIgnoreCase))
{
String^ sectionName = line->Substring(1, line->Length - 2);
if (String::IsNullOrWhiteSpace(sectionName))
continue;
currentSection = sectionName;
}
array<String^>^ parts = line->Split(gcnew array<wchar_t>(2) { '=' }, 2);
if (parts->Length == 1)
SetString(currentSection, parts[0]->Trim(), "");
else
SetString(currentSection, parts[0]->Trim(), parts[1]->Trim());
}
}
bool ContainsSection(String^ sectionName)
{
return _values->ContainsKey(sectionName);
}
bool ContainsValue(String^ sectionName, String^ valueName)
{
Dictionary<String^, String^>^ values = GetSection(sectionName);
if (values == nullptr)
return false;
return values->ContainsKey(valueName);
}
void Clear()
{
_values->Clear();
}
void SetString(String^ sectionName, String^ valueName, String^ value)
{
Dictionary<String^, String^>^ values = GetSection(sectionName);
if (values == nullptr)
{
values = gcnew Dictionary<String^, String^>(StringComparer::InvariantCultureIgnoreCase);
_values->Add(sectionName, values);
}
if (values->ContainsKey(valueName))
values[valueName] = value;
else
values->Add(valueName, value);
}
String^ GetString(String^ sectionName, String^ valueName, String^ defaultValue)
{
Dictionary<String^, String^>^ values = GetSection(sectionName);
if (values == nullptr)
return defaultValue;
if (values->ContainsKey(valueName))
return values[valueName];
return defaultValue;
}
private:
Dictionary<String^, Dictionary<String^, String^>^>^ _values;
Dictionary<String^, String^>^ GetSection(String^ sectionName)
{
if (_values->ContainsKey(sectionName))
return _values[sectionName];
return nullptr;
}
};
}
您应该添加错误检查,并且可以省略不需要的内容(例如部分和注释)。要“读取”不同的值类型,您可以实现更多GetXYZ()
方法来将结果解析GetString()
为所需的值(float
例如 a )。
另一种解决方案可能是......简单地导入本机函数来解析 INI。他们工作得很好!