プログラムを書こう!

実務や自作アプリ開発で習得した役に立つソフトウェア技術情報を発信するブログ

C++/CLI の INI ファイルで指定したセクションのキーと値を全て取得する

この記事は 2021 年 02 月 26 日に投稿しました。

f:id:paveway:20190914064630j:plain

目次

  1. はじめに
  2. C++/CLI の INI ファイルで指定したセクションのキーと値を全て取得する
  3. おわりに

1. はじめに

こんにちは、iOS のエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用している C++/CLI の INI ファイルで指定したセクションのキーと値を全て取得する方法についてです。

目次へ

2. C++/CLI の INI ファイルで指定したセクションのキーと値を全て取得する

C++/CLI の INI ファイルで指定したセクションのキーと値を全て取得するには、GetPrivateProfileSection関数を使用します。

書式

DWORD GetPrivateProfileSection(
    LPCTSTR lpAppName,
    LPTSTR lpszReturnBuffer,
    DWORD nSize,
    LPCTSTR lpFileName
);

引数

lpAppName
セクション名

lpszReturnBuffer
取得したキーと値が格納されるバッファへのポインタ
キーと値と次のキーと値は NULL 文字で区切られます。
終端には文字列の終端を示す NULL 文字が付加されます。

nSize
lpszRetrunBuffer のサイズ(文字数)

lpFileName
INI ファイルのファイルパス名

戻り値

取得したキーと値の文字数。
終端の NULL 文字は含みません。
取得したキーと値よりバッファサイズが小さい場合jはnSize - 2 が返却されます。

実装例

INI ファイル
[Section1]
Key11=Value11
Key12=Value12
Key13=Value13

[Section2]
Key21=Value21
Key22=Value22
Key23=Value23

[Section3]
Key31=Value31
Key32=Value32
Key33=Value33
main.cpp
#include <Windows.h>
#include <msclr/marshal_cppstd.h>
#include <tchar.h>

using namespace System;
using namespace System::Collections::Generic;

/**
 * @brief セクションのキーと値を全て取得します。
 *
 * @param [in] filePathName INIファイルのファイルパス名
 * @param [in] sectionName セクション名
 * @param [out] keyvalueTable 取得したキーと値を格納するテーブル
 * @return 処理結果(true:成功/false:エラー)
 */
bool GetSectionKeyValue(String^ filePathName, String^ sectionName, Dictionary<String^, String^>^% keyValueTable)
{
    // ファイルパス名をTCHAR配列に変換します。
    pin_ptr<const TCHAR> filePathNameChars = PtrToStringChars(filePathName);

    // セクション名をTCHAR配列に変換します。
    pin_ptr<const TCHAR> sectionNameChars = PtrToStringChars(sectionName);

    // 取得したキーと値を格納するバッファを用意します。
    TCHAR returnValue[1024];
    int returnValueLen = sizeof(returnValue) / sizeof(TCHAR);
    SecureZeroMemory(returnValue, returnValueLen);

    // 指定したセクションのキーと値を全て取得します。
    DWORD result = GetPrivateProfileSection(sectionNameChars, &returnValue[0], returnValueLen, filePathNameChars);

    // 読み込んだセクション名がバッファサイズを超える場合
    if (result == (returnValueLen - 2))
    {
        // エラーで終了します。
        return false;
    }

    // 読み込んだキーと値はNULL区切りの文字列になっているので、1つずつの文字列に変換します。
    array<String^>^ separator = gcnew array<String^> { "=" };
    for (TCHAR* pSeek = returnValue; *pSeek != NULL; pSeek += _tcslen(pSeek) + 1)
    {
        // "キー=値"の文字列に変換します。
        String^ item = gcnew String(pSeek);

        // キーと値を分割し、テーブルに格納します。
        array<String^>^ items = item->Split(separator, StringSplitOptions::None);

        // キーのみの場合
        if (items->Length != 2)
        {
            // 次の項目を処理する。
            continue;
        }

        // キーが空文字列か空白文字の場合
        String^ key = items[0];
        String^ value = items[1];
        if (String::IsNullOrWhiteSpace(key))
        {
            // 次の項目を処理します。
            continue;
        }

        // テーブルにキーが存在する場合
        if (keyValueTable->ContainsKey(key))
        {
            // 値を更新します。
            keyValueTable[key] = value;
        }

        // テーブルにキーが存在しない場合
        else
        {
            // キーと値を追加します。
            keyValueTable->Add(key, value);
        }
    }
    return true;
}

[STAThreadAttribute]
int main()
{
    String^ iniFileName = ".\\Sample.ini";
    Dictionary<String^, String^>^ keyValueTable = gcnew Dictionary<String^, String^>();
    GetSectionKeyValue(iniFileName, "Section1", keyValueTable);

    // 読み込んだキーと値を表示します。
    for each (String ^ key in keyValueTable->Keys)
    {
        String^ value = keyValueTable[key];
        Console::WriteLine("Key=" + key + " Value=" + value);
    }

    Console::ReadKey();
    return 0;
}

実行結果

Key=Key11 Value=Value11
Key=Key12 Value=Value12
Key=Key13 Value=Value13

API Reference

GetPrivateProfileSection関数

目次へ

3. おわりに

前回

www.paveway.info

の関連となります。

紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。

目次へ


私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッド OS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOS モバイルアプリウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。

また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。

EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688

目次へ