2012-05-07 9 views
0

Visual Studio 2008でC++/CLIを使用してプログラムをビルドしていますが、既定のユーザーディレクトリ設定をtxtファイルに保存しようとしています。これまでのところ、私はそれを保存してtxtファイルの中でこれを見せました。INIファイルを解析する

Input Directory=C:\Input 
Output Directory=C:\Output 

問題は、私のプログラムが「入力ディレクトリ=」という単語をどのように検出し、その後ろの単語だけを取りますか?

テキストファイル内の特定の単語を検索してC++/CLIで置き換える方法はありますか?だから私は "C:\ Input"を検索し、それを "D:\ Input"と置き換えることができます。

+0

これは一種のINIファイルですか?ネイティブ関数をインポートできますか? –

+0

いいえ、作成したtxtファイルに保存されます。 – Hearty

+0

はい、構文がINIファイルに類似しているとは限りません。 –

答えて

0

単純な解決策を見つけるのに苦労した後、私は@Hans Passantの示唆するように "Input Directory ="を省略し、第1行目を入力フォルダ、第2行目を出力フォルダとして読み取ることで、 thisと同様のテクニックを使用して設定します。

回答したすべての方に感謝します。

1

多くの方法でファイルから読み込むことができます。 C++ \ cliを使用する利点の1つは、あなたが非常に修道院のネットインタフェースを利用できることです。

だからFile::ReadAllLinesを使用することができますし、それは、次の操作を行い解析するために、私はそれがINIのような構文ですが、節なしとし、文字列「入力ディレクトリ」

+0

たとえば、私がReadAllLinesを使用して[String :: Contains](http://msdn.microsoft.com/en-us/library/dy85x1sa.aspx)メソッドを使用して "Input Directory"を検索する方法がありますが、 "C:\ Input"という文字列を使用しますか? – Hearty

1

のためのそれぞれの行をスキャンします。 (たとえば)ファイル解析に使用しますクラスのコンストラクタで

  • は、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を解析するためのネイティブ関数をインポートすることです。彼らはかなりうまくいく!

+0

ありがとうございますが、実装の例を挙げることができますか?手順3で "="が検出された後、文字列の一部をどのように取ることができますか? – Hearty

+1

はい、私はいくつかのコードを投稿します(認識されていませんテストされて...) –

+0

初心者プログラマーとして、あなたが投稿したものは私を超えています。しかし、努力してくれてありがとう、私は正直にそれを感謝します。 – Hearty

関連する問題