Tastatur Codes und Namen linken in beide Richtungen
-
Hi Leute,
ich möchte gern meine Tastaturcode (char) mit den Namen der Tasten verknüpfen (std::string). Wie mach ich das am besten?
Ich habe mich schon nach set, multiset und map, multimap erkundigt, aber so wie ich das verstehe funktioniert die Zuordnung da nur in 1 Richtung. Ich brauche aber beide Richtungen.
char -> std::string
std::string -> char
Also zu einem Code (char) will ich den Namen (std::string) auslesen können und zu einem Namen (std::string) will ich den Code (char) haben.Zwei Maps kommen im Moment auch nicht in Frage, da ich ja dann auch beide synchron halten muss und die Fehlerquote ist mir zu hoch.
Gruß
Scarabol
-
boost.bimap
-
pack doch einfach beide maps in eine eigene Klasse, die sich um die Synchronität kümmert. Nach außen hin bietest du dann einfach zwei Methoden oder []Operatoren string -> char und char -> string an.
greetz KN4CK3R
-
Boost hat eine
bimap, das könnte's sein...
-
Oder klassisch einfach zwei Felder. Tastaturcodes klingt so, als gäbe es höchstens 100-200, da könnte eine direkte Suche noch eine akzeptable Laufzeit haben und du hast dann bei sonstigen Zugriffen schön einfache Strukturen. Du kannst auch das Feld, welches häufiger durchsucht wird sortieren, dann hast du in diese Richtung sogar log(N) Suchzeit.
-
vorrausgesetzt er schreibts auch ordentlich und in bisschen auf speed.
andererseits, bei den mengen kann er auch gleich nicht nur 2 arrays nehmen sondern gleich 4 um in beide richtungen alles sortiert haben
-
Skym0sh0 schrieb:
vorrausgesetzt er schreibts auch ordentlich und in bisschen auf speed.
andererseits, bei den mengen kann er auch gleich nicht nur 2 arrays nehmen sondern gleich 4 um in beide richtungen alles sortiert habenDann hat er ja wieder seine Synchronisationsprobleme
.(Der Smiley will heißen, dass das ein selbst gemachtes Problem ist. Siehe KN4CK3Rs Beitrag wie man so etwas idiotensicher lösen kann)
-
wow, danke für die vielen Antworten. Bin noch nicht so weit, aber um das Problemchen nochmal deutlicher zu machen.
Ich hab zwei ziemlich lange Listen mit den Namen und den Codes für die einzelnen Tasten. Im Programm selber brauch ich dann Funktionen die mir für einen bestimmten Code den Tastennamen zurückliefern und für einen Tastennamen einen Code zurückliefern. Im Moment verfolge ich noch die bimap Methode. Wie ich das in einer eigenen Klasse machen kann, hab ich schon versucht aber kriegs nicht hin...
Gruß
Scarabol
-
Wenn boost.bimap ausscheidet kannst du ja vielleicht sowas verwenden. ShortCut könnte man zur Not durch std::pair ersetzen, aber ich würd´ das explizit ausformulieren.
#include <string> #include <vector> #include <algorithm> #include <functional> // Klasse zum Ablegen der Key/Name Paare struct ShortCut // oder was auch immer { char Key; std::string Name; ShortCut() : Key( 0 ) { } ShortCut( char Key, const std::string Name ) : Key( Key ), Name( Name ) { } }; // Prädikat zum Suchen nach Paaren anhand des Keys struct ShortCutEqualsKey : std::unary_function<ShortCut,bool> { char Key; ShortCutEqualsKey ( char Key ) : Key( Key ) { } bool operator()( const ShortCut& op ) const { return op.Key == Key; } }; // Prädikat zum Suchen nach Paaren anhand des Namen struct ShortCutEqualsName : std::unary_function<ShortCut,bool> { std::string Name; ShortCutEqualsName( const std::string& Name ) : Name( Name ) { } bool operator()( const ShortCut& op ) const { return op.Name == Name; } }; int main() { std::vector<ShortCut> ShortCuts; ShortCuts.push_back( ShortCut( 'a', "Aaaargh!" ) ); ShortCuts.push_back( ShortCut( 'b', "Bäh!" ) ); std::vector<ShortCut>::iterator i1 = std::find_if( ShortCuts.begin(), ShortCuts.end(), ShortCutEqualsKey ( 'a' ) ); std::vector<ShortCut>::iterator i2 = std::find_if( ShortCuts.begin(), ShortCuts.end(), ShortCutEqualsName ( "Bäh!" ) ); }
-
Oder irgendwas mit einem statischen mapping:
//impl.h #ifndef INCLUDE_GUARD #define INCLUDE_GUARD unsigned char find(std::string const & s); std::string find(unsigned char c); #endif//impl.cpp #include "impl.h" namespace { typedef std::array<char const *, 42> lookup_table_type; lookup_table_type make_key_map() { lookup_table_type table; table[0] = "bla"; table[1] = "blub"; table[2] = "laber"; //... table[41] = "das_wars"; return table; } lookup_table_type const & get_key_map() { static lookup_table_type key_map = make_key_map(); return key_map; } } unsigned char find(std::string const & s) { lookup_table_type::const_iterator p = std::find(get_key_map().begin(), get_key_map().end(), s); if(p == get_key_map().end()) { throw exception(); } //evtl. noch einen offset auf die distanz rechnen, je nach mapping return std::distance(get_key_map().begin(), p); } std::string find(unsigned char c) { //evtl. noch einen offset auf c rechnen, je nach mapping if(c >= get_key_map().size()) { throw exception(); } return get_key_map()[c]; }
-
Und wat machste, wenn die Keycodes nicht linear von 0-41 gehen?
-
Dann hast Du Pech. Aber hier fehlen Informationen für genaue Lösungen.
-
Die Codes sind nicht linear und haben auch keine Beziehungen zueinander...
Gruß
Scarabol