連想配列

  VC++ COM



Scripting.Dictionary が、連想配列の機能を持っており、VBScript 等でも使用されるので、
C++ でもそれを利用します。

実用では、ユーザのクラスでラップし、演算子のオーバロードを行うと良いとおもいますが、
実際使った事が無いので、問題点はあるかもしれません

  
#include <windows.h>
#include <stdio.h>
#undef GetFreeSpace
#import "C:\WINDOWS\System32\scrrun.dll"

inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};

int main(int argc, char* argv[])
{
	CoInitialize(NULL);

	Scripting::IDictionaryPtr pDic;

	try {
		TESTHR(pDic.CreateInstance("Scripting.Dictionary"));

		_variant_t Key,Value;

		// 追加
		Key = "A";
		Value = "日本語";
		pDic->Add( &Key, &Value );

		// 追加
		Key = "B";
		Value = "表示";
		pDic->Add( &Key, &Value );

		// 追加
		Key = "XXX";
		Value = "面倒なので、文字列のみ";
		pDic->Add( &Key, &Value );

		// 置き換え
		Key = "B";
		Value = "【表示】";
		pDic->PutItem( &Key, &Value );

		_bstr_t str;

		printf( "要素数 : %d\n", pDic->GetCount() );

		// Key による参照
		Key = "A";
		str = pDic->GetItem( &Key );
		printf( "GetItem で直接表示 : %s\n", (LPTSTR)str );

		_variant_t ar;

		ar = pDic->Keys();

		SAFEARRAY *psa;
		long lLBound, lUBound, cElements;  

		psa = ar.parray;

		// 配列の下位および上位の境界を取得
		SafeArrayGetLBound( psa, 1, &lLBound );
		SafeArrayGetUBound( psa, 1, &lUBound );

		// 要素数を計算
		cElements = lUBound - lLBound + 1;

		// 列挙
		printf( "----------------------\n");
		for ( long cCnt = lLBound; cCnt <= lUBound; cCnt++ ) {
			VARIANT vVal;
			SafeArrayGetElement( psa, &cCnt, &vVal );
			Key = vVal;
			str = pDic->GetItem( &Key );
			printf( "%s\n", (LPTSTR)str );
		}

	}
	catch (_com_error &e)
	{
	}

	pDic.Release();

	CoUninitialize();
	return 0;
}
  

build.bat
  
cmd.exe /c vc.bat hash
  

vc.bat
  
Set AddPath=C:\Program Files\Microsoft Visual Studio\COMMON\MSDev98\Bin
Set PATH=%AddPath%;%PATH%
Set CL6="C:\Program Files\Microsoft Visual Studio\VC98\Bin\cl.exe"
Set LINK6="C:\Program Files\Microsoft Visual Studio\VC98\Bin\link.exe"
Set INC6="C:\Program Files\Microsoft Visual Studio\VC98\Include"
Set INCA="C:\Program Files\Microsoft Visual Studio\VC98\ATL\Include"
Set LIB6="C:\Program Files\Microsoft Visual Studio\VC98\Lib"
Set LIBS1=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
Set LIBS2=shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
%CL6% %1.cpp /c /I%INC6% /I%INCA% /GX
%LINK6% /LIBPATH:%LIB6% %1.obj %LIBS1% %LIBS2%
  
↑Visual C++ 6.0

  
Set AddPath=C:\Program Files\Microsoft Visual Studio 8\Common7\IDE
Set PATH=%AddPath%;%PATH%
Set CL8="C:\Program Files\Microsoft Visual Studio 8\VC\bin\cl.exe"
Set LINK8="C:\Program Files\Microsoft Visual Studio 8\VC\bin\link.exe"
Set INC81="C:\Program Files\Microsoft Visual Studio 8\VC\include"
Set INC82="C:\Program Files\Microsoft Platform SDK\Include"
Set INC83="C:\Program Files\Microsoft Platform SDK\Include\atl"
Set LIB81="C:\Program Files\Microsoft Visual Studio 8\VC\lib"
Set LIB82="C:\Program Files\Microsoft Platform SDK\Lib"
Set LIBS1=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
Set LIBS2=shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
%CL8% %1.cpp /c /I%INC81% /I%INC82% /I%INC83% /EHsc
%LINK8% /LIBPATH:%LIB81% /LIBPATH:%LIB82% %1.obj %LIBS1% %LIBS2%
  
↑Visual C++ 2005 Express Edition + SDK



  VB + Framework ( C# )



Msdn2 のサンプル通りです。

↓VB と C# のサンプルがあります
http://msdn.microsoft.com/ja-jp/library/xfhwa508(VS.80).aspx

作成とコレクション取得・列挙の部分が違いますが、基本同じです

  
Imports System
Imports System.Collections.Generic

Module Example

Sub Main() 

	Dim openWith As New Dictionary(Of String, String)

	openWith.Add("txt", "notepad.exe")
	openWith.Add("bmp", "paint.exe")
	openWith.Add("dib", "paint.exe")
	openWith.Add("rtf", "wordpad.exe")

	' **************************************************
	' 同一キーで Add はエラー
	' **************************************************
	Try
		openWith.Add("txt", "winword.exe")
	Catch 
		Console.WriteLine("An element with Key = ""txt"" already exists.")
	End Try

	' **************************************************
	' 参照
	' **************************************************
	Console.WriteLine("For key = ""rtf"", value = {0}.", _
		openWith("rtf"))

	' **************************************************
	' 置き換え
	' **************************************************
	openWith("rtf") = "winword.exe"
	Console.WriteLine("For key = ""rtf"", value = {0}.", _
		openWith("rtf"))

	' **************************************************
	' 追加も可
	' **************************************************
	openWith("doc") = "winword.exe"

	' **************************************************
	' 無いとエラー
	' **************************************************
	Try
		Console.WriteLine("For key = ""tif"", value = {0}.", _
			openWith("tif"))
	Catch 
		Console.WriteLine("Key = ""tif"" is not found.")
	End Try

	' **************************************************
	' 別の参照方法( 戻り値は bool )
	' **************************************************
	Dim value As String = ""
	If openWith.TryGetValue("tif", value) Then
		Console.WriteLine("For key = ""tif"", value = {0}.", value)
	Else
		Console.WriteLine("Key = ""tif"" is not found.")
	End If

	' **************************************************
	' 存在チェック
	' **************************************************
	If Not openWith.ContainsKey("ht") Then
		openWith.Add("ht", "hypertrm.exe")
		Console.WriteLine("Value added for key = ""ht"": {0}", _
			openWith("ht"))
	End If

	' **************************************************
	' 列挙
	' **************************************************
	Console.WriteLine()
	For Each kvp As KeyValuePair(Of String, String) In openWith
		Console.WriteLine("Key = {0}, Value = {1}", _
			kvp.Key, kvp.Value)
	Next kvp

	' **************************************************
	' 値のコレクションを取得
	' **************************************************
	Dim valueColl As _
		Dictionary(Of String, String).ValueCollection = _
			openWith.Values

	' **************************************************
	' 列挙
	' **************************************************
	Console.WriteLine()
	For Each s As String In  valueColl
		Console.WriteLine("Value = {0}", s)
	Next s

	' **************************************************
	' キーのコレクションを取得
	' **************************************************
	Dim keyColl As _
		Dictionary(Of String, String).KeyCollection = _
			openWith.Keys

	' **************************************************
	' 列挙
	' **************************************************
	Console.WriteLine()
	For Each s As String In  keyColl
	    Console.WriteLine("Key = {0}", s)
	Next s

	' **************************************************
	' 削除
	' **************************************************
	Console.WriteLine(vbLf + "Remove(""doc"")")
	openWith.Remove("doc")

	' **************************************************
	' クリア
	' **************************************************
	Console.WriteLine(vbLf + "{0}", openWith.Count )
	openWith.Clear()
	Console.WriteLine("{0}", openWith.Count )


End Sub

End Module
  

↓C#で連想配列作成
  
Dictionary<string, string> openWith = new Dictionary<string, string>();
  

↓C#で列挙
  
foreach( KeyValuePair<string, string> kvp in openWith ) {
	Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}

Dictionary<string, string>.ValueCollection valueColl = openWith.Values;

foreach( string s in valueColl ) {
	Console.WriteLine("Value = {0}", s);
}

Dictionary<string, string>.KeyCollection keyColl = openWith.Keys;

foreach( string s in keyColl ) {
	Console.WriteLine("Key = {0}", s);
}
  










  infoboard   管理者用   
このエントリーをはてなブックマークに追加





フリーフォントWEBサービス
SQLの窓WEBサービス

SQLの窓フリーソフト

素材

一般WEBツールリンク

SQLの窓

フリーソフト

JSライブラリ