のためのそれぞれの行をスキャンします。 (たとえば)ファイル解析に使用しますクラスのコンストラクタで
:
- は、
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
)に解析することができます。
もう1つの解決策は、単純にINIを解析するためのネイティブ関数をインポートすることです。彼らはかなりうまくいく!
これは一種のINIファイルですか?ネイティブ関数をインポートできますか? –
いいえ、作成したtxtファイルに保存されます。 – Hearty
はい、構文がINIファイルに類似しているとは限りません。 –